[剑指offer]面试题第[54]题[JAVA][二叉搜索树的第k大节点][递归][迭代]

239 篇文章 1 订阅
【问题描述】[简单]
给定一棵二叉搜索树,请找出其中第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

【解答思路】

反向中序遍历
遍历到第k个节点时,直接返回改节点值,如果未找到,则返回0
在这里插入图片描述

1. 递归

在这里插入图片描述
时间复杂度:O(N) 空间复杂度:O(1)

class Solution {
    int res, k;
    public int kthLargest(TreeNode root, int k) {
        this.k = k;
        dfs(root);
        return res;
    }
    void dfs(TreeNode root) {
        if(root == null) return;
        dfs(root.right);
        if(k == 0) return;
        if(--k == 0) res = root.val;
        dfs(root.left);
    }
}




nt count=0, res=0;//形参k不能随着dfs的迭代而不断变化,为了记录迭代进程和结果,引入类变量count和res。
    public int kthLargest(TreeNode root, int k) {
        this.count=k;//利用形参值k对类变量count进行初始化
        dfs(root);//这里不要引入形参k,dfs中直接使用的是初始值为k的类变量count
        return res;            
    }
    public void dfs(TreeNode root){
        if(root==null||count==0) return;//当root为空或者已经找到了res时,直接返回
        dfs(root.right);
        if(--count==0){//先--,再判断
            res = root.val;
            return;//这里的return可以避免之后的无效迭代dfs(root.left);
        }
        dfs(root.left);  
    }
2. 迭代

如下图(5,3,7,2,4,6,8) 中,按节点数值大小顺序第三小结点的值为4
在这里插入图片描述
在这里插入图片描述
时间复杂度:O(N) 空间复杂度:O(1)

class Solution {
    // 反向中序遍历,当遍历到第k个节点时,返回该节点值
    public int kthLargest(TreeNode root, int k) {
        // count用于指示已经查找过的数字个数
        int count=0;
        TreeNode p= root;
        Stack<TreeNode> stack=new Stack<>();
        while(p!=null||!stack.isEmpty()){
            if(p!=null){
                stack.push(p);
                p=p.right;
            }else{
                p=stack.pop();
                count++;
                if(count==k) return p.val;
                p=p.left;
            }
        }
        return 0;
    }
}




2. 入队

时间复杂度:O(N) 空间复杂度:O(N)

class Solution {
    public int kthLargest(TreeNode root, int k) {
        // 在中序遍历的同时,把值加入表中
        ArrayList<Integer> list = new ArrayList();
        r(root,list);

        //话说倒数第k个数,下标是多少来着?诶,倒数第一个数下标是size-1诶,那么倒数第k个数不就是
        return list.get(list.size() - k);
    }

    // 二叉树递归形式中序遍历
    void r(TreeNode root, List list){
        if(root == null) return ;
        r(root.left,list);
        list.add(root.val);
        r(root.right,list);
    }
}

class Solution {
    public int kthLargest(TreeNode root, int k) {
        List<Integer> result = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.right;
            }
            cur = stack.pop();
            result.add(cur.val);
            cur = cur.left;
        }
        return result.get(k - 1);
    }
}


【总结】
1. 二叉搜索树中序遍历 有序递增序列 中序逆序遍历 有序递减序列
2.二叉树遍历
  • 前序遍历 先输出当前结点的数据,再依次遍历输出左结点和右结点
  • 中序遍历 先遍历输出左结点,再输出当前结点的数据,再遍历输出右结点
  • 后续遍历 先遍历输出左结点,再遍历输出右结点,最后输出当前结点的数据
3. 二叉树 递归 栈

转载链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/mian-shi-ti-54-er-cha-sou-suo-shu-de-di-k-da-jie-d/

参考链接::https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/sou-suo-er-cha-shu-de-zhong-xu-bian-li-jiu-shi-di-/

参考链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/fan-xiang-zhong-xu-bian-li-fei-di-gui-die-dai-miao/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值