二叉搜索树迭代器 II
难度:
标签:
题目描述
代码结果
运行时间: 295 ms, 内存: 48.9 MB
/*
* Leetcode 1586: 二叉搜索树迭代器 II
*
* 题目思路:
* 1. 使用Java Stream API,我们仍需要对树进行中序遍历并存储结果。
* 2. 可以利用Stream的collect()方法来将中序遍历的节点收集到List中。
* 3. 其他逻辑与普通Java实现类似。
*/
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class BSTIteratorStream {
private List<TreeNode> inorderList;
private int currentIndex;
public BSTIteratorStream(TreeNode root) {
inorderList = new ArrayList<>();
inorderList = inorderTraversal(root).collect(Collectors.toList());
currentIndex = -1;
}
// 使用Stream进行中序遍历
private Stream<TreeNode> inorderTraversal(TreeNode node) {
if (node == null) return Stream.empty();
return Stream.concat(
Stream.concat(inorderTraversal(node.left), Stream.of(node)),
inorderTraversal(node.right)
);
}
public boolean hasNext() {
return currentIndex + 1 < inorderList.size();
}
public TreeNode next() {
if (!hasNext()) throw new IllegalStateException("No next element");
currentIndex++;
return inorderList.get(currentIndex);
}
public boolean hasPrev() {
return currentIndex - 1 >= 0;
}
public TreeNode prev() {
if (!hasPrev()) throw new IllegalStateException("No previous element");
currentIndex--;
return inorderList.get(currentIndex);
}
}
解释
方法:
这个题解实现了一个二叉搜索树的双向迭代器,支持获取当前节点的前驱和后继节点。主要思路是:
1. 初始化时,将根节点到最左叶子节点的路径压入栈中。
2. 获取下一个节点时,如果当前节点有右子树,则将当前节点压栈,并将右子树的最左路径压入栈,当前节点指向右子树的最左叶子;否则弹出栈顶节点,直到栈顶节点是当前节点的父节点,当前节点指向该父节点。
3. 获取上一个节点时,如果当前节点有左子树,则把当前节点压栈,并将左子树的最右路径压入栈,当前节点指向左子树的最右叶子;否则弹出栈顶节点,直到栈顶节点是当前节点的父节点,当前节点指向该父节点。
4. 判断是否有下一个节点,当前节点为空时,看栈是否为空;当前节点不为空时,若有右子树则必有下一个,否则看栈中节点是否为当前节点的父节点。
5. 判断是否有上一个节点,若当前节点为空则没有;若当前节点有左子树则必有上一个,否则看栈中节点是否为当前节点的父节点。
时间复杂度:
初始化:O(n);next()和prev():平均O(1),最坏O(n);hasNext()和hasPrev():平均O(1),最坏O(n)
空间复杂度:
平均空间复杂度是O(log(n)),最坏情况是O(n)
代码细节讲解
🦆
在定义二叉搜索树迭代器时,如何保证迭代器的初始状态是正确的,特别是在处理空树或只有一个节点的树时?
▷🦆
在`next`方法中,如果当前节点为空且栈也为空,如何处理这种情况?是否应该抛出异常或返回特定的值?
▷🦆
在`prev`方法中,如果没有前驱节点,为什么选择将当前节点压栈并将当前节点置空?这样的处理方式会对后续的迭代有何影响?
▷🦆
在处理`hasNext`和`hasPrev`方法时,如何有效地判断栈中的节点是否为当前节点的父节点,特别是在复杂的树结构中?
▷