剑指–二叉搜索树的第k大节点
1,题目:
2,思路:
方法一:中序遍历后续+提前返回:
中序遍历倒序 + 提前返回
- 1.为求第 kk 个节点,需要实现以下 三项工作 :
- 2.递归遍历时计数,统计当前节点的序号;
- 3.递归到第 k 个节点时,应记录结果 res ;
- 4.记录结果后,后续的遍历即失去意义,应提前终止(即返回)
。
递归解析:
- 1.终止条件: 当节点 root 为空(越过叶节点),则直接返回;
- 2.递归右子树: 即dfs(root.right) ;
- 3.三项工作:
- 4.提前返回: 若 k=0 ,代表已找到目标节点,无需继续遍历,因此直接返回;
- 5.统计序号: 执行 k=k−1 (即从 k 减至 0 );
- 6.记录结果: 若 k=0 ,代表当前节点为第 k 大的节点,因此记录 res=root.val ;
- 7.递归左子树: 即 dfs(root.left) ;
下面是对应的图解:
这个用中序遍历是最简单的。
3,代码:
方法一:中序遍历后续+提前返回:
class Solution {
/*
中序遍历倒序 + 提前返回
1.为求第 kk 个节点,需要实现以下 三项工作 :
2.递归遍历时计数,统计当前节点的序号;
3.递归到第 k 个节点时,应记录结果 res ;
4.记录结果后,后续的遍历即失去意义,应提前终止(即返回)。
递归解析:
1.终止条件: 当节点 root 为空(越过叶节点),则直接返回;
2.递归右子树: 即dfs(root.right) ;
3.三项工作:
4.提前返回: 若 k=0 ,代表已找到目标节点,无需继续遍历,因此直接返回;
5.统计序号: 执行 k=k−1 (即从 k 减至 0 );
6.记录结果: 若 k=0 ,代表当前节点为第 k 大的节点,因此记录 res=root.val ;
7.递归左子树: 即 dfs(root.left) ;
*/
int res, k;
public int kthLargest(TreeNode root, int k) {
this.k = k;
dfs(root);
return res;
}
void dfs(TreeNode root) {
if(root == null) return;
dfs(root.right);
if(k == 0) return;
if(--k == 0) res = root.val;
dfs(root.left);
}
}