锯齿迭代器
难度:
标签:
题目描述
代码结果
运行时间: 33 ms, 内存: 16.3 MB
/*
* 思路:
* 使用 Java Stream API 来实现锯齿迭代器。
* 这里主要的思路是先合并两个列表,再按照交替顺序排序。
* 将两个列表中的元素分成一个列表中的奇数索引和偶数索引,然后交替合并它们。
*/
import java.util.*;
import java.util.stream.*;
public class ZigzagIteratorStream {
private List<Integer> mergedList;
private Iterator<Integer> iterator;
public ZigzagIteratorStream(List<Integer> v1, List<Integer> v2) {
List<Integer> combinedList = Stream.concat(v1.stream(), v2.stream()).collect(Collectors.toList());
List<Integer> zigzagList = new ArrayList<>();
int size1 = v1.size(), size2 = v2.size();
int maxSize = Math.max(size1, size2);
for (int i = 0; i < maxSize; i++) {
if (i < size1) zigzagList.add(v1.get(i));
if (i < size2) zigzagList.add(v2.get(i));
}
this.mergedList = zigzagList;
this.iterator = mergedList.iterator();
}
public int next() {
return iterator.next();
}
public boolean hasNext() {
return iterator.hasNext();
}
}
解释
方法:
这个题解使用队列(deque)来实现锯齿迭代器。初始化时,将非空的输入数组及其初始下标 0 作为元组依次加入队列。每次调用 next() 方法时,从队首取出当前要迭代的数组和下标,返回当前元素,并将下标加 1。如果更新后的下标没有超出数组范围,则将新的元组加入队尾。hasNext() 方法则遍历队列中的所有元组,判断是否存在还未迭代完的数组。
时间复杂度:
O(m+n+k)
空间复杂度:
O(1)
代码细节讲解
🦆
为何在设计锯齿迭代器时选择使用`deque`而不是其他类型的数据结构如列表或链表?
▷🦆
初始化`ZigzagIterator`时,如果输入的数组中存在长度远不同,这种实现方式是否会导致某些数组迭代结束得更快?如何处理这种情况以保持锯齿形迭代?
▷🦆
在`next`方法中,如果当前数组已迭代完成,是否考虑过将队列的这个元组直接丢弃,而不是检查后再次加入队列?这样做的优缺点是什么?
▷🦆
请问`hasNext`方法中遍历队列来检查是否还有元素未迭代的操作,是否会影响整体性能?能否优化此方法以减少不必要的遍历?
▷相关问题
二叉搜索树迭代器
实现一个二叉搜索树迭代器类
BSTIterator
,表示一个按中序遍历二叉搜索树(BST)的迭代器:
BSTIterator(TreeNode root)
初始化BSTIterator
类的一个对象。BST 的根节点root
会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。boolean hasNext()
如果向指针右侧遍历存在数字,则返回true
;否则返回false
。int next()
将指针向右移动,然后返回指针处的数字。
注意,指针初始化为一个不存在于 BST 中的数字,所以对 next()
的首次调用将返回 BST 中的最小元素。
你可以假设 next()
调用总是有效的,也就是说,当调用 next()
时,BST 的中序遍历中至少存在一个下一个数字。
示例:

输入 ["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(); // 返回 3 bSTIterator.next(); // 返回 7 bSTIterator.hasNext(); // 返回 True bSTIterator.next(); // 返回 9 bSTIterator.hasNext(); // 返回 True bSTIterator.next(); // 返回 15 bSTIterator.hasNext(); // 返回 True bSTIterator.next(); // 返回 20 bSTIterator.hasNext(); // 返回 False
提示:
- 树中节点的数目在范围
[1, 105]
内 0 <= Node.val <= 106
- 最多调用
105
次hasNext
和next
操作
进阶:
- 你可以设计一个满足下述条件的解决方案吗?
next()
和hasNext()
操作均摊时间复杂度为O(1)
,并使用O(h)
内存。其中h
是树的高度。
窥视迭代器
请你在设计一个迭代器,在集成现有迭代器拥有的 hasNext
和 next
操作的基础上,还额外支持 peek
操作。
实现 PeekingIterator
类:
PeekingIterator(Iterator<int> nums)
使用指定整数迭代器nums
初始化迭代器。int next()
返回数组中的下一个元素,并将指针移动到下个元素处。bool hasNext()
如果数组中存在下一个元素,返回true
;否则,返回false
。int peek()
返回数组中的下一个元素,但 不 移动指针。
注意:每种语言可能有不同的构造函数和迭代器 Iterator
,但均支持 int next()
和 boolean hasNext()
函数。
示例 1:
输入: ["PeekingIterator", "next", "peek", "next", "next", "hasNext"] [[[1, 2, 3]], [], [], [], [], []] 输出: [null, 1, 2, 2, 3, false] 解释: PeekingIterator peekingIterator = new PeekingIterator([1, 2, 3]); // [1,2,3] peekingIterator.next(); // 返回 1 ,指针移动到下一个元素 [1,2,3] peekingIterator.peek(); // 返回 2 ,指针未发生移动 [1,2,3] peekingIterator.next(); // 返回 2 ,指针移动到下一个元素 [1,2,3] peekingIterator.next(); // 返回 3 ,指针移动到下一个元素 [1,2,3] peekingIterator.hasNext(); // 返回 False
提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 1000
- 对
next
和peek
的调用均有效 next
、hasNext
和peek
最多调用1000
次
进阶:你将如何拓展你的设计?使之变得通用化,从而适应所有的类型,而不只是整数型?
扁平化嵌套列表迭代器
给你一个嵌套的整数列表 nestedList
。每个元素要么是一个整数,要么是一个列表;该列表的元素也可能是整数或者是其他列表。请你实现一个迭代器将其扁平化,使之能够遍历这个列表中的所有整数。
实现扁平迭代器类 NestedIterator
:
NestedIterator(List<NestedInteger> nestedList)
用嵌套列表nestedList
初始化迭代器。int next()
返回嵌套列表的下一个整数。boolean hasNext()
如果仍然存在待迭代的整数,返回true
;否则,返回false
。
你的代码将会用下述伪代码检测:
initialize iterator with nestedList res = [] while iterator.hasNext() append iterator.next() to the end of res return res
如果 res
与预期的扁平化列表匹配,那么你的代码将会被判为正确。
示例 1:
输入:nestedList = [[1,1],2,[1,1]]
输出:[1,1,2,1,1]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,1,2,1,1]
。
示例 2:
输入:nestedList = [1,[4,[6]]]
输出:[1,4,6]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,4,6]
。
提示:
1 <= nestedList.length <= 500
- 嵌套列表中的整数值在范围
[-106, 106]
内