leetcode:173. 二叉搜索树迭代器
题目
实现一个二叉搜索树迭代器类 BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
BSTIterator(TreeNode root)初始化BSTIterator类的一个对象。BST 的根节点root会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。boolean hasNext()如果向指针右侧遍历存在数字,则返回true;否则返回false。int next()将指针向右移动,然后返回指针处的数字。
注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。
你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。
进阶:
- 你可以设计一个满足下述条件的解决方案吗?
next()和hasNext()操作均摊时间复杂度为O(1),并使用O(h)内存。其中h是树的高度。
示例:![[中等] 173. 二叉搜索树迭代器 - 图1](/uploads/projects/liangduo-rjrcs@ggu4wq/88ac7c3676397d65b19c328f2ba08d59.png)
输入["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"][[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]输出[null, 3, 7, true, 9, true, 15, true, 20, false]解释BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);bSTIterator.next(); // 返回 3bSTIterator.next(); // 返回 7bSTIterator.hasNext(); // 返回 TruebSTIterator.next(); // 返回 9bSTIterator.hasNext(); // 返回 TruebSTIterator.next(); // 返回 15bSTIterator.hasNext(); // 返回 TruebSTIterator.next(); // 返回 20bSTIterator.hasNext(); // 返回 False
解答 & 代码
解法一:保存中序遍历结果
始化 BSTIterator 时先对二叉搜索树进行中序遍历,并将结果保存在数组 inOrderList 中。设置一个 idx 用来遍历数组即可
/*** 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 {private:vector<int> inOrderList; // 中序数组int idx; // 当前访问到的数组下标// 迭代中序遍历二叉搜索树,将结果保存在 inOrderListvoid inOrder(TreeNode* root){stack<TreeNode*> s;TreeNode* cur = root;while(cur != nullptr || !s.empty()){while(cur != nullptr){s.push(cur);cur = cur->left;}cur = s.top();s.pop();inOrderList.push_back(cur->val);cur = cur->right;}}public:BSTIterator(TreeNode* root) {inOrder(root);idx = 0;}int next() {++idx;return inOrderList[idx - 1];}bool hasNext() {return idx < inOrderList.size();}};/*** Your BSTIterator object will be instantiated and called as such:* BSTIterator* obj = new BSTIterator(root);* int param_1 = obj->next();* bool param_2 = obj->hasNext();*/
复杂度分析:设二叉树节点数为 n,高度为 h
- 时间复杂度:初始化时间复杂度 O(n),后续
next()和hasNext()的时间复杂度均为 O(1) - 空间复杂度 O(n):数组
inOrderList保存中序遍历的全部结果
执行结果:
执行结果:通过
执行用时:28 ms, 在所有 C++ 提交中击败了 45.03% 的用户
内存消耗:23.5 MB, 在所有 C++ 提交中击败了 42.81% 的用户
解法二:迭代
将迭代法中序遍历二叉树分解到 next()
/**
* 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 {
private:
stack<TreeNode*> s;
TreeNode* cur;
public:
BSTIterator(TreeNode* root) {
cur = root;
}
int next() {
while(cur != nullptr)
{
s.push(cur);
cur = cur->left;
}
cur = s.top();
s.pop();
int val = cur->val;
cur = cur->right;
return val;
}
bool hasNext() {
return cur != nullptr || !s.empty();
}
};
/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator* obj = new BSTIterator(root);
* int param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/
复杂度分析:设二叉树节点数为 n,高度为 h
- 时间复杂度:初始化和调用
hasNext()的时间复杂度都为 O(1)。n 次调用next()遍历全部 n 个节点,总的时间复杂度 O(n),每次的均摊时间复杂度 O(1) - 空间复杂度 O(h):栈深度 = 二叉树深度
执行结果:
执行结果:通过
执行用时:44 ms, 在所有 C++ 提交中击败了 6.90% 的用户
内存消耗:23.4 MB, 在所有 C++ 提交中击败了 70.33% 的用户
