二叉搜索树的第k大节点

题目描述

给定一棵二叉搜索树,请找出其中第k大的节点。
示例 1:

1
2
3
4
5
6
7
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
  2
输出: 4

示例 2:

1
2
3
4
5
6
7
8
9
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4

限制:
1 ≤ k ≤ 二叉搜索树元素个数

题目链接

Leetcode

题目解答

解法一

中序遍历,二叉搜索树的一大特性就是其中序遍历得到的结果是一个升序排列的序列,第k大的节点就是序列的倒数第k个位置对应的值。

时间复杂度:$O(n)$ 空间复杂度:$O(n)$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int kthLargest(TreeNode root, int k) {
List<Integer> list = new ArrayList<>();
inOrder(root, list);
return list.get(list.size() - k);
}

public void inOrder(TreeNode root, List<Integer> list) {
if (root == null) return;
inOrder(root.left, list);
list.add(root.val);
inOrder(root.right, list);
}
}

执行用时:1 ms, 在所有 Java 提交中击败了41.36%的用户
内存消耗:38.4 MB, 在所有 Java 提交中击败了35.10%的用户

解法二

正常的中序遍历对树节点的访问顺序是左-根-右,这样访问得到的序列是按升序排列的,目标是要找到第k大的节点,如果我们按照右-根-左的节点顺序访问,能够得到降序的序列,这样访问的第k个节点就是第k大的节点,就不用访问所有节点了,时间空间效率也能得到提升。

时间复杂度:$O(k)$ 空间复杂度:$O(k)$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {

public int cnt = 0;

public int kthLargest(TreeNode root, int k) {
if (root == null) return 0;
int right = kthLargest(root.right, k);
if (++cnt == k) {
return root.val;
}
int left = kthLargest(root.left, k);
return Math.max(left, right);
}
}

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.7 MB, 在所有 Java 提交中击败了99.92%的用户

-------------本文结束 感谢您的阅读-------------

文章对您有帮助,可以打赏一杯咖啡,鼓励我继续创作!