Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
leetcode 剑指 Offer 54. 二叉搜索树的第k大节点
给定一棵二叉搜索树,请找出其中第 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 ≤二叉搜索树元素个数
二、思路分析
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)
二叉搜索树:右子树上面所有的节点都大于根节点,左子树上面的节点都小于根节点。这也就意味着右子树节点大于左子树节点
那么进行中序遍历(左根右)时,左子树都小于根节点,右子树都大于根节点,且遍历时递归式操作的,也就意味着对于任何一个节点其前面的都小于它,后面的都大于它。
通过上面所讲可知,排序二叉树的中序遍历结果就是一个有序序列。
递归
无需展开理解,利用递归函数的语意信息去进行程序设计。
解题思路①:
- 明确找到第k大的节点;
- 在二叉搜索树,右子树是一群较大值得节点集合;左子树是一群较小值得节点集合
- 假设右子树节点个数为 count_right;
- 如果 k <= count_right,那么第k大节点一定在右子树上
- 如果 k == count_right + 1, 那么第k大节点就是根节点
- 如果 k > count_right + 1, 那么第k大节点一定在左子树上
解题思路②: 对二叉搜索树进行中序遍历然后取第k个节点
三、JavaScript代码
/**
* 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}
*/
// 思路1
// function getCount(root) {
// if(root == null) return 0;
// return getCount(root.left) + getCount(root.right) + 1;
// }
// var kthLargest = function(root, k) {
// let count_right = getCount(root.right);
// if(count_right >= k) return kthLargest(root.right, k);
// if(count_right+1 == k) return root.val;
// if(count_right < k) return kthLargest(root.left, k - count_right - 1)
// };
// 思路2
function in_order(root,ans) {
if(root == null) return;
in_order(root.left, ans);
ans.push(root.val);
in_order(root.right, ans)
}
var kthLargest = function(root, k) {
let ans = [];
in_order(root, ans);
return ans[ans.length - k]
};