二叉搜索树的第k个节点
给定一棵二叉搜索树,请找出其中的第 k 小的结点。
你可以假设树和 k 都存在,并且 1≤k 树的总结点数。
数据范围
树中节点数量 [1,500][1,500][1,500]。
样例
输入:root = [2, 1, 3, null, null, null, null] ,k = 3
2
/ \
1 3
输出:3
算法思路
该算法使用**中序遍历(DFS)**来查找二叉搜索树(BST)中第 k 小的节点。由于 BST 的中序遍历结果是升序排列的,因此只需遍历到第 k 个节点即可。
- 递归中序遍历:
- 先递归遍历左子树。
- 访问当前节点时,
k--
,如果k == 0
,说明当前节点是第 k 小的节点,保存结果。 - 如果
k > 0
,继续递归遍历右子树。
- 终止条件:
- 当
k == 0
时,提前终止遍历,避免不必要的递归。
- 当
- 时间复杂度:O(k),最坏情况下(k = n)需要遍历整棵树,平均情况下只需遍历到第 k 个节点。
- 空间复杂度:O(h),其中 h 是树的高度,递归栈的深度取决于树的高度。最坏情况下(树退化为链表)为 O(n),平均情况下(平衡 BST)为 O(log n)。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* ans; // 存储最终结果的节点指针
// 主函数:返回BST中第k小的节点
TreeNode* kthNode(TreeNode* root, int k) {
dfs(root, k); // 调用DFS中序遍历查找第k小的节点
return ans; // 返回结果
}
// 辅助函数:中序遍历BST,并找到第k小的节点
void dfs(TreeNode* root, int& k) {
// 递归终止条件:当前节点为空
if(!root) return;
// 1. 先递归遍历左子树(中序遍历顺序:左->根->右)
dfs(root->left, k);
// 2. 处理当前节点
k--; // 每访问一个节点,k减1
if(!k) { // 当k减到0时,说明当前节点就是第k小的节点
ans = root; // 保存结果
return; // 提前终止遍历(优化)
}
// 3. 只有当k>0时才需要继续遍历右子树(优化:避免不必要遍历)
if(k > 0) {
dfs(root->right, k);
}
}
};
关键说明
ans
变量- 用于存储最终找到的第k小节点
kthNode()
主函数- 入口函数,初始化DFS遍历
- 返回最终结果
dfs()
辅助函数- 采用标准中序遍历(左-根-右)顺序
- 通过引用传递
k
实现计数功能 - 关键优化:
if(!k) return
找到结果后立即终止遍历if(k>0)
只在必要时遍历右子树
- 递归终止条件
- 遇到空节点时直接返回
- 计数逻辑
- 每访问一个有效节点就执行
k--
- 当
k==0
时说明找到目标节点
- 每访问一个有效节点就执行