剑指 Offer 54. 二叉搜索树的第k大节点

 

思路:

 一开始完全思路就搞错了,想了一个类似与递归的思路,先找到最大的,然后一步一步找次大的,

又因为如何找父亲节点的事想了一阵

结果突然发现,可以直接输出成一个数组啊,然后直接取数组就行了

class Solution {
    List<Integer> list=new ArrayList<>();
    public int kthLargest(TreeNode root, int k) {
        if(root==null)
        {return 0;}
        //中序遍历输出一个数组
        tree2List(root);
        return list.get(list.size()-k);
    }
    public void tree2List(TreeNode root)
    {
        if(root==null)
        {return;}
        if(root.left!=null)
        {tree2List(root.left);}
        list.add(root.val);
        if(root.right!=null)
        {tree2List(root.right);}
    }
}

这里需要注意,这个列表需要弄成全局变量(类的变量)

另外dfs时不需要判断子树为null,直接

void dfs(TreeNode root) {
    if(root == null) return;
    dfs(root.right); //
    System.out.println(root.val); //
    dfs(root.left); //
}

问题当然很明显,无论k为多少,都直接把整个树都中序遍历了

忘记了中序遍历可以交换顺序(右子树,节点,左子树)

然后再加入一个计数器,这样能在计到k的时候直接返回

  int 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);  
    }

理解:

处理节点的顺序是严格按照从大到小的

然后每次处理count--了

因此当count等于0了,就直接该返回了

要多想想递归

要多想想dfs

要多想想二叉搜索树

原文地址:https://www.cnblogs.com/take-it-easy/p/14349820.html