zoukankan      html  css  js  c++  java
  • [LeetCode] 230. Kth Smallest Element in a BST 二叉搜索树中的第K小的元素

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

    Note: 
    You may assume k is always valid, 1 ≤ k ≤ BST's total elements.

    Example 1:

    Input: root = [3,1,4,null,2], k = 1
       3
      / 
     1   4
      
       2
    Output: 1

    Example 2:

    Input: root = [5,3,6,2,4,null,null,1], k = 3
           5
          / 
         3   6
        / 
       2   4
      /
     1
    Output: 3
    

    Follow up:
    What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

    给一个二叉树,写一个找到第k小元素的函数。Follow up: 二叉树经常被修改,需要频繁找第k小的元素,如何优化。

    解法1:提示让用BST的性质来,那就是BST数值大小是:左<根<右,用中序遍历所有的节点就会得到一个有序数组,如果只求第k小的数,还可以用一个计数器记录已经遍历的节点数,只遍历到第k个节点返回即可。

    解法2: 新的题目里已经去掉提示了,所以也可以有别的解法。

    Hint:

    Try to utilize the property of a BST.
    What if you could modify the BST node's structure?
    The optimal runtime complexity is O(height of BST).

    1、计算左子树元素个数left。

    2、 left+1 = K,则根节点即为第K个元素, left >= k, 则第K个元素在左子树中,left +1 < k, 则转换为在右子树中,寻找第K-left-1元素。

    Java:

    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode p = root;
        while(p!=null){
            stack.push(p);
            p=p.left;
        }
        int i=0;
        while(!stack.isEmpty()){
            TreeNode t = stack.pop();
            i++;
     
            if(i==k)
                return t.val;
     
            TreeNode r = t.right;
            while(r!=null){
                stack.push(r);
                r=r.left;
            }
     
        }
     
        return -1;
    }
    

    Java:

    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
     
        TreeNode p = root;
        int result = 0;
     
        while(!stack.isEmpty() || p!=null){
            if(p!=null){
                stack.push(p);
                p = p.left;
            }else{
                TreeNode t = stack.pop();
                k--;
                if(k==0)
                    result = t.val;
                p = t.right;
            }
        }
     
        return result;
    }    

    Python:

    def kthSmallest(root, k):
        stack = []
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            k -= 1
            if k == 0:
                return root.val
            root = root.right

    Python:

    class Solution:
        # @param {TreeNode} root
        # @param {integer} k
        # @return {integer}
        def kthSmallest(self, root, k):
            s, cur, rank = [], root, 0
    
            while s or cur:
                if cur:
                    s.append(cur)
                    cur = cur.left
                else:
                    cur = s.pop()
                    rank += 1
                    if rank == k:
                        return cur.val
                    cur = cur.right
    
            return float("-inf")  

    C++:Iteration

    class Solution {
    public:
        int kthSmallest(TreeNode* root, int k) {
            int cnt = 0;
            stack<TreeNode*> s;
            TreeNode *p = root;
            while (p || !s.empty()) {
                while (p) {
                    s.push(p);
                    p = p->left;
                }
                p = s.top(); s.pop();
                ++cnt;
                if (cnt == k) return p->val;
                p = p->right;
            }
            return 0;
        }
    };
    

    C++:Recursion

    class Solution {
    public:
        int kthSmallest(TreeNode* root, int k) {
            return kthSmallestDFS(root, k);
        }
        int kthSmallestDFS(TreeNode* root, int &k) {
            if (!root) return -1;
            int val = kthSmallestDFS(root->left, k);
            if (k == 0) return val;
            if (--k == 0) return root->val;
            return kthSmallestDFS(root->right, k);
        }
    }; 

    C++:

    class Solution {
    public:
        int kthSmallest(TreeNode* root, int k) {
            if(root==NULL)
                return 0;
            int leftSize=calNode(root->left);
            if(leftSize+1 == k)
                return root->val;
            else if(leftSize+1 < k)
                return kthSmallest(root->right,k-leftSize-1);
            else
                return kthSmallest(root->left,k);
        }
        
        int calNode(TreeNode *head){
            if(head==NULL)
                return 0;
            return calNode(head->left)+calNode(head->right)+1;
        }
    };
    

      

    类似题目:

    [LeetCode] 94. Binary Tree Inorder Traversal 二叉树的中序遍历

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    Flash 报表之 LineChart & PieChart
    TVS二极管的选型和应用测试计算实例
    中兴招聘面试问题:有源晶振输出串个电阻做啥用?
    EPCS 无法配置FPGA的解决方法以及JTAG、AS调试总结
    ADS8364 VHDL程序正式版
    TVS二极管选型指南
    PID整定方法
    TVS瞬态电压抑制二极管(钳位二极管)原理参数
    高边和低边电流检测技术分析
    灵活使用示波器触发功能,帮助大大提高测量效率
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8606836.html
Copyright © 2011-2022 走看看