欢迎访问LeetCode题解合集
题目描述
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 next()
将返回二叉搜索树中的下一个最小的数。
示例:
[HTML_REMOVED]
[HTML_REMOVED]
BSTIterator iterator = new BSTIterator(root);
iterator.next(); // 返回 3
iterator.next(); // 返回 7
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 9
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 15
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 20
iterator.hasNext(); // 返回 false
提示:
-
next()
和hasNext()
操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。 -
你可以假设
next()
调用总是有效的,也就是说,当调用next()
时,BST 中至少存在一个下一个最小的数。
题解:
观察 next()
是返回二叉搜索树中下一个最小值,而二叉搜索树有一个重要的特征:中序遍历是递增序列 ,那么就可以考虑用 中序遍历 来搞事情。
直观想法是:中序遍历将值保存起来,然后 next()
时依次取出来即可,但是这种情况下,空间复杂度为 $O(n)$ ,与 $O(h)$ 不符。
可以考虑将非递归中序遍历,每次 next()
操作时,将栈顶节点右儿子的左节点全部入栈,这样最坏情况为 $O(n)$,均摊情况下为 $O(1)$
hasNext()
操作可直接判断栈是否为空。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
moveLeft( root );
}
void moveLeft(TreeNode* root) {
while ( root ) {
stk.push(root);
root = root->left;
}
}
int next() {
auto now = stk.top();
stk.pop();
int val = now->val;
now = now->right;
moveLeft( now );
return val;
}
bool hasNext() {
return !stk.empty();
}
private:
stack<TreeNode*> stk;
};
/*
时间:24ms,击败:97.68%
内存:23.4MB,击败:93.26%
*/
还可以考虑将 二叉搜索树 转换成 单链表,利用节点空闲的右指针,Morris遍历 将其改造成一个单链表。
时间复杂度:$O(n)$
额外空间复杂度:$O(1)$
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
now = root;
}
int next() {
while( now ) {
auto mostright = now->left;
if( mostright ) {
while ( mostright->right && mostright->right != now )
mostright = mostright->right;
if ( !mostright->right ) {
mostright->right = now;
now = now->left;
continue;
}
}
break;
}
int val = now->val;
now = now->right;
return val;
}
bool hasNext() {
return now != nullptr;
}
private:
TreeNode *now;
};
/*
时间:32ms,击败:86.96%
内存:23.4MB,击败:93.62%
*/