[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 题目汇总

 

 

 

posted @ 2018-03-20 02:30  轻风舞动  阅读(816)  评论(0编辑  收藏  举报