[路飞] leetcode 剑指 Offer 54. 二叉搜索树的第k大节点

143 阅读2分钟

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),(又:二叉搜索树,二叉排序树)

二叉搜索树:右子树上面所有的节点都大于根节点,左子树上面的节点都小于根节点。这也就意味着右子树节点大于左子树节点

那么进行中序遍历(左根右)时,左子树都小于根节点,右子树都大于根节点,且遍历时递归式操作的,也就意味着对于任何一个节点其前面的都小于它,后面的都大于它。

通过上面所讲可知,排序二叉树的中序遍历结果就是一个有序序列。

image.png

递归

无需展开理解,利用递归函数的语意信息去进行程序设计。

解题思路①:

  • 明确找到第k大的节点;
  • 在二叉搜索树,右子树是一群较大值得节点集合;左子树是一群较小值得节点集合
  • 假设右子树节点个数为 count_right;
  • 如果 k <= count_right,那么第k大节点一定在右子树上
  • 如果 k == count_right + 1, 那么第k大节点就是根节点
  • 如果 k > count_right + 1, 那么第k大节点一定在左子树上

image.png

解题思路②: 对二叉搜索树进行中序遍历然后取第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]
};

四、总结