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.

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?

Hint:

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

Solution 2, C++ with circular vector

Using a vector of fixed size k and a stack pointer i into it which will be used modulo k.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        vector<TreeNode*> stac(k);
        int i = 0, j = k;
        while (true) {
            while (root) {
                stac[i++%k] = root;
                root = root->left;
            }
            root = stac[--i%k];
            if (! --j)
                return root->val;
            root = root->right;
        }
    }
};

 

Solution 3, C++ with deque

I really like the previous version, but the fixed size k isn't always necessary, so here's a version using a deque:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        deque<TreeNode*> stac;
        while (true) {
            while (root) {
                stac.push_front(root);
                while (stac.size() > k)
                    stac.pop_back();
                root = root->left;
            }
            root = stac.front();
            stac.pop_front();
            if (! --k)
                return root->val;
            root = root->right;
        }        
    }
};

 

 

线索

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        TreeNode *left;
        int ans;
        while (root){
            if (root->left){
                left = root->left;
                while (left->right && left->right != root) left = left->right;
                if (left->right == root){
                    left->right = NULL;
                    if (--k == 0) ans = root->val; //cannot just return, need to recover the tree
                    root = root->right;
                }else{
                    if (k <= 0) root = root->right;
                    else{ // if find the kth, we will not travel new subtree.
                        left->right = root;
                        root = root->left;
                    }
                }
            }else{
                if (--k == 0) ans = root->val;
                root = root->right;
            }
        }
        return ans;
    }

};

 

posted on 2015-07-09 08:52  风云逸  阅读(70)  评论(0)    收藏  举报