86 · Binary Search Tree Iterator
Algorithms
Hard
Description
Design an iterator over a binary search tree with the following rules:
Next() returns the next smallest element in the BST.
Elements are visited in ascending order (i.e. an in-order traversal)
next() and hasNext() queries run in O(1)O(1) time in average.
Example
Example 1:
Input:
tree = {10,1,11,#,6,#,12}
Output:
[1,6,10,11,12]
Explanation:
The BST is look like this:
10
/
1 11
\
6 12
You can return the inorder traversal of a BST [1, 6, 10, 11, 12]
Example 2:
Input:
tree = {2,1,3}
Output:
[1,2,3]
Explanation:
The BST is look like this:
2
/
1 3
You can return the inorder traversal of a BST [1,2,3]
Challenge
Extra memory usage O(h), h is the height of the tree.
Super Star: Extra memory usage O(1)
Tags
Related Problems
448
Inorder Successor in BST
Medium
540
Zigzag Iterator
Medium
541
Zigzag Iterator II
Medium
915
Inorder Predecessor in BST
Medium
解法1:
利用In-Order Traversal的思路。
引用自九章
https://www.jiuzhang.com/solution/binary-search-tree-iterator/#tag-highlight-lang-java
这是一个非常通用的利用 stack 进行 Binary Tree Iterator 的写法。
stack 中保存一路走到当前节点的所有节点,stack.peek() 一直指向 iterator 指向的当前节点。
因此判断有没有下一个,只需要判断 stack 是否为空
获得下一个值,只需要返回 stack.peek() 的值,并将 stack 进行相应的变化,挪到下一个点。
挪到下一个点的算法如下:
如果当前点存在右子树,那么就是右子树中“一路向西”最左边的那个点
如果当前点不存在右子树,则是走到当前点的路径中,第一个左拐的点
注意:
- 该方法的next()的平均时间复杂度是O(1)。因为不管什么样的二叉树,每个节点都只进/出栈一次。平均起来,时间复杂度就是O(1)。
最坏时间复杂度应该是O(n)???
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
* Example of iterate a tree:
* BSTIterator iterator = BSTIterator(root);
* while (iterator.hasNext()) {
* TreeNode * node = iterator.next();
* do something for node
*/
class BSTIterator {
public:
/*
* @param root: The root of binary tree.
*/
BSTIterator(TreeNode * root) {
while(root) {
s.push(root);
root=root->left;
}
}
/*
* @return: True if there has next node, or false
*/
bool hasNext() {
return !s.empty();
}
/*
* @return: return next node
*/
TreeNode * next() {
TreeNode* node = s.top();
TreeNode* retNode = node;
if (node->right) {
node = node->right;
while (node) {
s.push(node);
node = node->left;
}
} else {
node = s.top();
s.pop();
while(!s.empty() && s.top()->right == node) {
node = s.top();
s.pop();
}
}
return retNode;
}
private:
stack<TreeNode*> s;
};
二刷:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
* Example of iterate a tree:
* BSTIterator iterator = BSTIterator(root);
* while (iterator.hasNext()) {
* TreeNode * node = iterator.next();
* do something for node
*/
class BSTIterator {
public:
/*
* @param root: The root of binary tree.
*/
BSTIterator(TreeNode * root) {
cur = root;
}
/*
* @return: True if there has next node, or false
*/
bool hasNext() {
return cur || !stk.empty();
}
/*
* @return: return next node
*/
TreeNode * next() {
while (cur) {
stk.push(cur);
cur = cur->left;
}
cur = stk.top();
stk.pop();
TreeNode *res = cur;
cur = cur->right;
return res;
}
private:
TreeNode *cur;
stack<TreeNode *> stk;
};
注意:上面的next()就是in-order traversal里面的两个while()循环去掉第一个while()循环。
vector<int> inorderTraversal(TreeNode *root) {
stack<TreeNode *> stk;
vector<int> res;
while (root || !stk.empty()) {
while (root) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}