持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
题目
给定一棵二叉搜索树,请找出其中第 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 大的节点
- 使用递归的方式,进行中序遍历
- 每经历一个父节点时,k--,直到 k == 0 时,返回当前值
代码
/**
* Definition for a binary tree node.
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
int res;
int k;
public int kthLargest(TreeNode root, int k) {
this.k = k;
dfs(root);
return res;
}
public void dfs(TreeNode root) {
if (root == null) return;
dfs(root.right); // 右
if (--k == 0) {
res = root.val;
return;
}
dfs(root.left); // 左
}
}
总结
性能分析
- 执行耗时:0 ms,击败了 100.00% 的 Java 用户
- 内存消耗:41 MB,击败了 27.37% 的 Java 用户
解题二:栈
思路
二叉搜索树的特性:左子树的最大值 < 父节点的值 < 右子树的最小值
按照二叉搜索树的特性,我们可以将问题转换为中序遍历二叉树,寻找中序遍历中第 K 大的节点
- 使用栈的方式,按照中序遍历,将遍历的节点存入 stack
- 每存入一个节点时,k--,直到 k == 0 时,返回当前值
代码
/**
* 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) {
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.isEmpty() || root != null) {
if (root != null) {
stack.push(root);
root = root.right;
} else {
root = stack.pop();
if(--k==0){
return root.val;
}
root = root.left;
}
}
return -1;
}
}
总结
性能分析
- 执行耗时:1 ms,击败了 28.81% 的 Java 用户
- 内存消耗:41.2 MB,击败了 18.17% 的 Java 用户