[leetcode] 173. Binary Search Tree Iterator 解题报告

题目链接:https://leetcode.com/problems/binary-search-tree-iterator/

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.


思路:这题是要快速求一个二叉搜索数是否有下一个最小结点。我们知道二叉搜索数的性质,结点左边的值比根节点小,结点右边的值比根节点大。那么利用这个性质可以知道最小的结点应该是在最左边,其实也就是中序遍历是依次增大的。知道了这样我们其实可以利用一个栈将所有结点按照: 根->右结点->左节点的方式入栈然后再依次出栈即可。这样在时间复杂度上可以达到O(1),但空间复杂度是O(n),n为结点个数。这样不符合要求的O(h)的时间复杂度。

我们还可以初始只让根的左子树入栈直到最左结点,每次结点出栈的时候再把他的右子树入栈,这样就可以达到O(h)的时间复杂度。举个栗子:

         4

    2       7

1    3   6   8

这样一个二叉搜索树,先依次让4->2->1入栈,每次调用next函数则让一个元素出栈。

第一次调用next的时候1出栈。

第二次调用next的时候2出栈,因为2有右子树,因此让2的右子树3入栈

第三次调用next的时候3出栈

第四次调用next的时候4出栈,并且4有右子树,但是此时4的右子树并不是最小结点,他还有左子树,因此一直遍历到左子树的叶子结点,依次入栈。

重复以上操作即可。

平均时间复杂度还是O(1),空间复杂度降为O(h)。

代码如下:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        if(!root) return;
        while(root)
        {
            st.push(root);
            root = root->left;
        }
    }

    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !st.empty();
    }

    /** @return the next smallest number */
    int next() {
        TreeNode* tem= st.top();
        int val = tem->val;
        st.pop();
        tem = tem->right;
        while(tem)
        {
            st.push(tem);
            tem = tem->left;
        }
        return val;
    }
private:
    stack<TreeNode*> st;
};

/**
 * Your BSTIterator will be called like this:
 * BSTIterator i = BSTIterator(root);
 * while (i.hasNext()) cout << i.next();
 */


你可能感兴趣的:(LeetCode,tree,binary)