每日一题--二叉搜索树的第k大节点

122 阅读2分钟

这是我参与11月更文挑战的第16天,活动详情查看:[2021最后一次更文挑战]

题目 给定一棵二叉搜索树,请找出其中第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 ≤ 二叉搜索树元素个数

思路

给定一棵二叉搜索树,请找出其中第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 ≤ 二叉搜索树元素个数 复杂度分析: 时间复杂度 O(N)O(N) : 当树退化为链表时(全部为右子节点),无论 kk 的值大小,递归深度都为 NN ,占用 O(N)O(N) 时间。 空间复杂度 O(N)O(N) : 当树退化为链表时(全部为右子节点),系统使用 O(N)O(N) 大小的栈空间。 代码: 题目指出:1 \leq k \leq N1≤k≤N (二叉搜索树节点个数);因此无需考虑 k > Nk>N 的情况。 若考虑,可以在中序遍历完成后判断 k > 0k>0 是否成立,若成立则说明 k > Nk>N 。

代码

  1. 二叉搜索树的节点的 右树值 > 节点值 > 左树值
  2. 因此只需要做一个深度优先遍历,顺序就是右->中->左就行
  3. 当k <= 0的时候,说明已找到res,提前返回
 * 解法一:递归遍历每个节点,排序后,第K-1为第K大值
 * @param {TreeNode} root
 * @param {number} k
 * @return {number}
 */
var kthLargest = function(root, k) {
    const arr = new Set()
    const dfs = (root) => {
        if (root) {
            arr.add(root.val)
            dfs(root.left)
            dfs(root.right)
        }
    }
    dfs(root)
    const sortArr = Array.from(arr).sort((a,b) => b-a)
    return sortArr[k-1]
};

/**
 * 解法二:中序遍历的数组,第K-1为第K大值
 * @param {TreeNode} root
 * @param {number} k
 * @return {number}
 */
var kthLargest = function(root, k) {
    const arr = []
    const dfs = root => {
        if(root) {
            dfs(root.right)
            arr.push(root.val)
            dfs(root.left)
        }
    }
    dfs(root)
    return arr[k-1]
}