class Solution {
public int kthLargest(TreeNode root, int k) {
Stack<TreeNode> s = new Stack<>();
TreeNode cur = root;
int idx = 0;
while (cur != null || !s.isEmpty()) {
while (cur != null) {
s.push(cur);
cur = cur.right;
}
TreeNode node = s.pop();
if (++idx == k) return node.val;
if (node.left != null) cur = node.left;
}
return -1;
}
}
//二叉搜索树,中序遍历 右 根 左是递减的序列
func kthLargest(root *TreeNode, k int) int {
var Help func(root *TreeNode) //声明递归函数
var res int
Help = func(root *TreeNode){
if root == nil{
return
}
//右子树
if root.Right != nil{
Help(root.Right)
}
k --
if k == 0{
res = root.Val
}
//左子树
if root.Left != nil{
Help(root.Left)
}
}
Help(root) //调用递归
return res
}
var target int
var n int
func kthLargest(root *TreeNode, k int) int {
n = k
right_root_left(root)
return target
}
func right_root_left(root *TreeNode) {
if root == nil || n <= 0 {
return
}
right_root_left(root.Right)
n = n - 1
if n == 0 {
target = root.Val
}
right_root_left(root.Left)
}
class Solution {
List list = new ArrayList<>();
public int kthLargest(TreeNode root, int k) {
inorder(root);
return list.get(list.size()-k);
}
public void inorder(TreeNode root){
if(root==null) return;
inorder(root.left);
list.add(root.val);
inorder(root.right);
}
}
优化一下
class Solution {
int ans=0;
int count=0;
public int kthLargest(TreeNode root, int k) {
nothing(root,k);
return ans;
}
//反向中序遍历,从大往小走,第k个数的时候停止
public void nothing(TreeNode root,int k){
if(root.right!=null) nothing(root.right,k);
if(++count==k){
ans = root.val;
return;
}
if(root.left!=null) nothing(root.left,k);
}
}
class Solution {
private int res = 0, k = 0;
public int kthLargest(TreeNode root, int k) {
this.k = k;
dfs(root);
return res;
}
private void dfs(TreeNode root) {
// k < 0 做剪枝处理
if (root == null || k < 0) {
return;
}
dfs(root.right);
k --;
if (k == 0) {
res = root.val;
return;
}
dfs(root.left);
}
}
思路:按照右根左的顺序递归访问,期间维护变量i,直到++i k 就把当前val的值赋值给res 时间复杂度 O(N) 空间复杂度 O(N)
class Solution {
int i = 0;
int res = -1;
public int kthLargest(TreeNode root, int k) {
find(root, k);
return res;
}
public void find(TreeNode head, int k) {
if (head == null)
return;
find(head.right, k);
if (i == k)
return;
if (++i == k)
res = head.val;
find(head.left, k);
}
}
class Solution {
int count= 0;
List<Integer> list = new ArrayList<>();
public int kthLargest(TreeNode root, int k) {
f(root);
int[] arr = new int[count];
int j = count;
count--;
for(int i : list){
arr[count--] = i;
}
int num = 0;
Arrays.sort(arr);
for(int i = 0;i<j-k;i++)
num++;
return arr[num];
}
void f(TreeNode root){
if(root == null) return ;
list.add(root.val);
count++;
f(root.left);
f(root.right);
return ;
}
}
class Solution {
int a = 0;
int res = 0;
public int kthLargest(TreeNode root, int k) {
a = k;
f(root);
return res;
}
void f(TreeNode root){
if(root == null || a<0) return ;
if(root.right != null) f(root.right);
a--;
if(a == 0) res = root.val;
f(root.left);
}
}
class Solution {
//中序遍历在集合中
//时间复杂度O(n)
//空间复杂度O(n)
List<Integer> list = new ArrayList<>();
public int kthLargest(TreeNode root, int k) {
if(root==null) {
return 0;
}
middle(root);
int value = list.get(list.size()-k);
return value;
}
public void middle(TreeNode root){
if(root==null)return;
//if(root.left==null)list.add(root.val);
middle(root.left);
list.add(root.val);
middle(root.right);
}
}
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
if not root: return None
res,stark,num = [],[],root
while num or stark:
while num:
stark.append(num)
num = num.right
tem = stark.pop()
res.append(tem.val)
num = tem.left
return res[k-1]
class Solution {
List list = new ArrayList<>();
public int kthLargest(TreeNode root, int k) {
inorder(root);
return list.get(list.size() - k);
}
public void inorder(TreeNode root){
if(root == null) return;
inorder(root.left);
list.add(root.val);
inorder(root.right);
}
}
使用右根左,从大到小,利用count控制倒数的个数,及时截断
空间复杂度O(1)时间复杂度O(N)
class Solution {
int count;
int ans;
public int kthLargest(TreeNode root, int k) {
count = k;
inorder(root);
return ans;
}
public void inorder(TreeNode root){
if(root.right != null) inorder(root.right);
count--;
if(count == 0){
ans = root.val;
return ;
}
if(root.left != null) inorder(root.left);
}
}
class Solution {
public int kthLargest(TreeNode root, int k) {
traverse(root,k);
return res;
}
int res = 0;
int rank = 0;
public void traverse(TreeNode root,int k){
if(root == null){
return;
}
traverse(root.right,k);
rank++;
if(k == rank){
res = root.val;
return;
}
traverse(root.left,k);
}
}
共以下 35 个回答
第一反应是中序遍历然后get(size – k)
然后发现可以简化代码,不需要遍历所有元素
镜像 中序遍历(右、根、左) 非递归
时间O(n) 空间O(n)
用中序遍历特性
这个是来自leetcode jyd的代码,对python3还不太熟悉,不是很会使用类变量
思路一:将二叉搜索树的中序遍历结果用一个链表存储起来,然后通过下标去第k大的元素。时间和空间复杂度都为O(N)。
思路二: 层序遍历二叉搜索树(访问顺序为右中左)的同时递减k并判断k是否等于0来返回结果。时间复杂度最坏情况下为O(N),空间复杂度为O(N)。
思路三:稍微改变下中序遍历的顺序,为右中左,dfs实现,同时维护一个变量来判断是否为结果。这个变量为什么是类变量,而不是方法变量,方法变量的话递归时会有回溯操作,不好判断。时间复杂度最坏情况下为O(N),空间复杂度O(N)。
时间复杂度:O(n)
空间复杂度:O(n)
思路:按照右根左的顺序递归访问,期间维护变量i,直到++i k 就把当前val的值赋值给res
时间复杂度 O(N)
空间复杂度 O(N)
时间复杂度:O(N)
空间复杂度:O(N)
解题思路:二叉搜索树具有左子树的值<根节点<右子树的值的特性,改进中序遍历,使用右->中->左的顺序递归,得到从大到小的排列顺序,取出第K-1个值即为第K大的节点。
时间复杂度:O(n)递归最大深度为N,链表
空间复杂度:O(n)
//一个小技巧就是按照RNL的顺序遍历bijiaozhiguan
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int num;
int res;
bool fun(TreeNode root,int k){
if(!root) return false;
if(fun(root->right,k)) return true;
num++;
if(numk){
res=root->val;
return true;
}
if(fun(root->left,k)) return true;
return false;
}
int kthLargest(TreeNode* root, int k) {
num=0;
res=1;
fun(root,k);
return res;
};
解题思路:第k大,那么就是中序遍历,但是二叉搜索树中序遍历的结果是升序,求k大的将右子树、当前节点、左子树去做出这样的遍历。还有种方法,以中序遍历方式将其循环放入栈中,这样出栈顺序的结果就是从大到小
时间复杂度:O(n)
时间复杂度 on
中序遍历
先遍历获取树的所有val,然后存入数组,排序后求倒数第k个元素。
打卡完才看到是二叉搜索树,有点写复杂了。定义一个全局a,右中左遍历,当a=0时候,就查找到了第k个大的数。
时间 O(n)
空间O(n)
二叉搜索树中序遍历的倒序就是从大到小排列的,因此使用中序遍历即可求解
用的遍历模版,先开始写的前序遍历,然后再sort,没有明白二叉搜索树的性质,中序就已经是有序的了 时间复杂度O(n),空间复杂度O(n)
时间复杂度 O(n)
时间:O(n),空间:O(n)
按照中序遍历得到递增序列,使用list存储
时间复杂度O(N)空间复杂度O(N)
使用右根左,从大到小,利用count控制倒数的个数,及时截断
空间复杂度O(1)时间复杂度O(N)
利用搜索树中序遍历的特性,题目要求第k大,则从大到小遍历,先遍历右子树
时间复杂度为O(n),空间复杂度为O(lnn)