题目地址:
https://leetcode.com/problems/binary-search-tree-iterator-ii/
给定一棵二叉搜索树,要求实现一个迭代器,可以做如下操作:
1、BSTIterator(TreeNode root)
初始化一个迭代器,其应该指向该BST中序遍历第一个位置之前的那个位置;
2、boolean hasNext()
如果该迭代器可以后移,则返回true,否则返回false;
3、int next()
后移迭代器,并返回其指向的数值;
4、boolean hasPrev()
如果该迭代器可以前移,则返回true,否则返回false;
5、int prev()
前移迭代器,并返回其指向的数值。
普通的BST中序遍历迭代器可以用栈来实现,栈始终存的是一条左链,并且栈顶是将要遍历的下一个数字。这里还需要实现prev操作,可以再加上一个列表和一个指针,该列表存已经遍历过的数,按中序遍历的顺序存储,而指针指向当前遍历到的位置。在实现next的时候,如果指针不是指向列表里的最后一个数,那可以直接指针后移一位,取出列表中的那个元素;否则需要依靠迭代器取出下一个数,在返回之之前存入列表并后移指针。实现prev的时候直接在列表里查即可。代码如下:
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
public class BSTIterator {
private Deque<TreeNode> stk;
private List<TreeNode> list;
private int pos;
public BSTIterator(TreeNode root) {
pos = -1;
list = new ArrayList<>();
stk = new LinkedList<>();
while (root != null) {
stk.push(root);
root = root.left;
}
}
public boolean hasNext() {
return !stk.isEmpty() || pos + 1 < list.size();
}
public int next() {
pos++;
// 列表里有则取之
if (pos < list.size()) {
return list.get(pos).val;
}
// 否则依靠迭代器取出下一个数
TreeNode top = stk.pop(), right = top.right;
list.add(top);
while (right != null) {
stk.push(right);
right = right.left;
}
return top.val;
}
public boolean hasPrev() {
return pos > 0;
}
public int prev() {
return list.get(--pos).val;
}
}
class TreeNode {
int val;
TreeNode left, right;
public TreeNode(int val) {
this.val = val;
}
}
每个操作均摊时间复杂度 O ( 1 ) O(1) O(1),空间 O ( n ) O(n) O(n)。