二叉树——二叉搜索树中第K小的元素
题目要求:给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(k 从 1 开始计数)
二叉搜索树 中序遍历 = 从小到大有序数组
第 1 小就是中序第 1 个,第 k 小就是中序第 k 个。
解法:中序遍历 + 计数
class Solution {
int res = 0;
int count = 0;
public int kthSmallest(TreeNode root, int k) {
inorder(root, k);
return res;
}
// 中序:左 → 根 → 右
private void inorder(TreeNode node, int k) {
if (node == null) return;
inorder(node.left, k);
// 遍历到根时计数
count++;
if (count == k) {
res = node.val;
return;
}
inorder(node.right, k);
}
}
- BST 中序遍历严格递增
- 每访问一个节点就 count++
- 当 count == k 时,这个节点就是第 k 小
也可以是直接返回int的写法:
class Solution {
int count = 0;
public int kthSmallest(TreeNode root, int k) {
if (root == null) {
return -1;
}
int left = kthSmallest(root.left, k);
if (left != -1) {
return left;
}
count++;
if (count == k) {
return root.val;
}
return kthSmallest(root.right, k);
}
}
一、那为什么很多人不怎么写?
1. 递归是 “一路往上返”,你必须处理没找到的情况
- 找到目标节点 → return 值
- 没找到 → 必须 return 一个标记(比如 -1)
- 上层判断:如果不是 -1,说明找到了,直接往上返
如果你写成:
if(count == k) return node.val;
但不处理没找到的返回值,
Java 会直接编译报错:缺少返回语句。
2. count 必须是全局 / 成员变量
- 因为递归是深度优先来回跳,
- count 要在整个递归栈里共享计数,
- 不能写在方法内部当局部变量。
二、为什么要返回-1?
- 返回 -1 = 没找到
- 返回正常数字 = 找到了,直接往上传递结果
用这道题来理解一下递归的思想
这道题是通过中序遍历递归+计数来找到第K个节点。中序遍历的递归思想是左中右,先切换到递归左子树的视角,如果左子树到底了都没有找到,即if(nodenull)那么我就返回一个-1来表示递归左子树没有找到节点,接下来切换到根节点的视角,那么我需要先递归左子树,用left来接收递归左子树的返回值,int left = KthSmallest(node.left,k),如果找到了即if(left!=-1),那么直接返回left。后面我们就需要处理找到了的逻辑来设置left的值作为满足条件的节点值。如果没找到,那么接下来计入当前根 count++,然后判断当前节点是否满足条件即if(countk),如果当前节点满足条件,那么res = node.val,return res, 如果当前根节点也不满足,那么满足条件的节点一定是右子树,所以直接返回右子树的递归就可以了,return KthSmallest(node.right,k)。
浙公网安备 33010602011771号