• 230. Kth Smallest Element in a BST


    不要被题目迷惑,肯定是要O(N)的时间,在不改变数据结构的情况下。
    就是in-order traverse,因为是BST,所以遍历顺序是从小到大,遍历的第K个元素就是第K小的。

    可以Iteratively,也开始recursively.

    public class Solution 
    {   
        /* recursion version
        int count = 0;
        int res = 0;
        public int kthSmallest(TreeNode root, int k) 
        {
            
            helper(root,k);
            return res;
            
        }
        
        public void helper(TreeNode root, int k)
        {
            
            if(root == null || count == k) return;
            
    
            
            helper(root.left,k);
            count++;
            if(count == k)
            {
                res = root.val;
                return;
            }
            helper(root.right,k);
        }
        */
        
        public int kthSmallest(TreeNode root, int k)
        {
            int res = 0;
            int count = 0;
            
            Stack<TreeNode> stk = new Stack<TreeNode>();
            
            TreeNode temp = root;
            while(temp != null || !stk.isEmpty())
            {
                while(temp!=null)
                {
                    stk.push(temp);
                    temp = temp.left;
                }
                temp = stk.pop();
                count++;
                if(count == k)
                {
                    res = temp.val;
                    break;
                }
                if(count>=k)break;
                temp = temp.right;
            }
            
            return res;
        }
        
    }
    

    至于follow up,无非是如何提供信息,让每次左还是右能做出选择。Node的结构里直接加1个数表示第几小的,这样遍历就知道往左还是往右了。




    二刷

    又一次被follow up给迷惑了,以为有O(height)的做法,感觉要被刷新三观,实际上是没有的。

    利用in-order是sorted的特性按部就班地做就行了。

    Iterative:

    public class Solution {
        public int kthSmallest(TreeNode root, int k) {
            Stack<TreeNode> stk = new Stack<>();
            TreeNode temp = root;
            while (!stk.isEmpty() || temp != null) {
                while (temp != null) {
                    stk.push(temp);
                    temp = temp.left;
                }
                temp = stk.pop();
                if (--k == 0) {
                    return temp.val;
                }
                temp = temp.right;
            }
            
            return -1;
        }
    }
    

    Recursive:

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

    2个办法都很基础。。

    看了一下Discussion,剽窃到一个用二分的方法,实际情况会比较快。
    作者的名字真忘了,光记得他给了3种方法,剩下2种就是上面的2种,他说STACK那个是BFS,其实不是,是DFS。。。

    Binary-Search
    做到一半觉得不对,这他妈是TOP-DOWN啊,快个鸡巴。。最坏的情况是O(n^2)。。

    public class Solution {
    
        public int kthSmallest(TreeNode root, int k) {
    
            int left = getNum(root.left);  
            if (left + 1 < k) {
                return kthSmallest(root.right, k - left - 1);
            } else if (left + 1 > k) {
                return kthSmallest(root.left, k);
            } else {
                return root.val;
            }
        }
        
        public int getNum(TreeNode root) {
            if (root == null) return 0;
            return getNum(root.left) + getNum(root.right) + 1;
        }
        
        
    }
    

    但是实际binary search这个方法的思路就是题目中follow-up的思路。
    二分的时候,我们先算左边,如果左边总数比K小,我们直接去右边找就行了;如果总数比K大,就要去左边重新计算数量,很麻烦,但是如果提前改变结构,每个Node都知道左支有多少个,就不用每次都找了,可以直接判断。

    follow-up的答案就是先preprocess the entire tree...这样除了一开始的过程是O(n),用post-order,后来一直是O(Height)

  • 相关阅读:
    codevs2574 波兰表达式
    绿书模拟day10 单词前缀
    codevs2171 棋盘覆盖
    noip2008 双栈排序
    图论总结复习
    noip2010 关押罪犯
    flask使用geventwebsocket完成小型聊天系统
    MongoDB
    flask基础内容总览
    flask蓝图,cbv,python中的redis操作
  • 原文地址:https://www.cnblogs.com/reboot329/p/6103517.html
Copyright © 2020-2023  润新知