题目链接: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(); */