题目重点:逐个返回嵌套整数,缓存下一项保证重复hasNext不消费数据,并说明摊销成本。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练稳定int/list无环树,按左到右DFS返回整数;has_next可重复调用,耗尽next抛StopIteration。用list接口练习,实际NestedInteger封装需适配。
- 同题标签没有披露特定接口变体,本文合同不声称已有原始starter。输入遍历期间不修改。
解题路线
- constructor仅保存根iterator,不能立即flatten整个输入否则失去惰性与depth空间。_advance遇list进入子iterator、耗尽pop,遇int返回。
- has_next调用_advance并缓存一项;下一次has_next只查看缓存,next取缓存后清空。EMPTY独立object哨兵,0和负整数不与“没有值”混淆。
- 直接next且无缓存也可advance,两个调用路径共享核心,避免只有hasNext之后才能next的隐藏要求。
- 每list iterator耗尽最多一次、每item读取最多一次,因此总遍历O(M)。一次next可能跳过很多空list,不能保证单次最坏O(1);平均成本按整个结构元素摊销。
手动走一遍
[1,[[],2],0]重复三次has_next仍next返回1,再2、0,最后False;用if cached当bool会把0误认为无缓存,可能跳过它。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
EMPTY=object()
class NestedIterator:
"""Stable nested int/list tree, lazy DFS left-to-right; repeated has_next safe."""
def __init__(self,nested):self.stack=[iter(nested)];self.cached=EMPTY
def _advance(self):
while self.stack:
try:item=next(self.stack[-1])
except StopIteration:self.stack.pop();continue
if type(item) is int:return item
if isinstance(item,list):self.stack.append(iter(item))
else:raise TypeError('int/list only')
raise StopIteration
def has_next(self):
if self.cached is EMPTY:
try:self.cached=self._advance()
except StopIteration:return False
return True
def __iter__(self):return self
def __next__(self):
if self.cached is not EMPTY:
value=self.cached;self.cached=EMPTY;return value
return self._advance()
复杂度
constructor O(1),总遍历O(M)、辅助O(depth)加单项缓存。单次查询最坏O(M)经过空结构,若只有少量整数却大量空list,按返回整数摊销也不是固定常数。
易错点与追问
容易失分的边界
- has_next每次推进导致重复调用丢整数。
- eager flatten占O(整数数)空间且初始化扫描全部。
继续深挖
- 边遍历边修改children会怎样影响iterator,是否需snapshot合同?
- 想支持peek多项,需要有界buffer并说明空间/提前消费行为。
