// C++ intkthSmallest(TreeNode* root, int k){ stack<TreeNode*> s; // 初始化一个空栈 auto p = root; // 遍历到最左端的节点 while (p) { s.push(p); p = p->left; } // 目前栈顶为最小值 int i = 0; while (!s.empty()) { auto top = s.top(); s.pop(); ++i; if (i == k) { // 当弹出k个值时停止 return top->val; } top = top->right; if (top) { // 放入右子节点,并遍历到其最左端子节点 while (top) { s.push(top); top = top->left; } } } return-1; }
进阶:修改节点数据结构
思路
每个节点记录一个变量,表示该节点左子树的节点数。
假设根节点的左子树有 N 个节点。
如果k=N+1 ,则根节点为第k小的元素。
如果k<N,则需要在左子树中递归查找第k小的元素。
如果k>N+1,则需要在右子树中查找第k-N-1小的元素。
时间复杂度为O(h),h 为二叉树的高度。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// C++ intkthSmallest3(TreeNode* root, int k){ if (!root) { return-1; } auto p = root; while (p) { if (p->lCount + 1 == k) { return p->val; } elseif (k > p->lCount) { k = k - (p->lCount + 1); p = p->right; } else { p = p->left; } } return-1; }