题目
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
限制:
- 1 ≤ k ≤ 二叉搜索树元素个数
题解
题目给的是二叉搜索树,简单的思路是通过中序遍历可以得到 root 的升序数组num1, 如: root = [3,1,4,null,2], 中序遍历后: nums1 = [ null, 1, 2, 3,4], 得到升序数组后reverse反转后,二叉搜索树的第k 大 节点即 nums[k-1];
中序遍历的模板
- 遍历左节点
- 遍历根节点
- 遍历右节点
function inorder(root) {
if (root == null) return;
inorder(root.left);
console.log(root.val);
inorder(root.right);
}
那么可以实现不用一个数组nums1保存中序遍历的结果吗?
答案当然是可以的!
使用中序遍历的倒序可以得到root降序排列nums2, 如root = [3,1,4,null,2], 中序遍历的倒序后: nums2 = [4, 3, 2, 1, null], 观察下nums2发现,如果第 1大节点, 就是中序遍历的倒序的访问的第一个节点。依次类推,在倒序遍历中,每访问一个节点k--, 如果当k == 0,说明当前节点是第K大的节点,
中序遍历的倒序模板
function inorderReverse(root) {
if (root == null) return;
inorder(root.right);
console.log(root.val);
inorder(root.left);
}
参考代码
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthLargest = function(root, k) {
// 保存当前遍历的节点值
let res;
function inorderReverse(root) {
if (root == null) return;
inorderReverse(root.right);
// 如果k <= 0, 此时不需要再遍历了,说明已经找到了
if (k <= 0) return;
if (--k == 0) {
res = root.val;
}
inorderReverse(root.left);
}
inorderReverse(root);
return res;
};