SWE · Coding

数组offset到数据流:正数取前缀,负数保留末尾

负offset必须读取流结束,前缀则可提前停止。

题目重点:负offset必须读取流结束,前缀则可提前停止。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • offset≥0取前offset项;offset<0取后|offset|项;超长度返回全部可用,0返回空。
  • 流有限且只读一次,不要求返回后能重读已消费部分。

解题路线

  1. 正数用最多k次next即可,不预读第k+1项。负数用容量k的deque,每新项自动淘汰最老,结束后队列就是后k项。
  2. 区别成本:前缀在无限流也可终止;后缀需要明确end-of-stream,在无限流上没有最终答案。
  3. 若hasNext/getNext来自外部接口,确认hasNext是否有读取副作用及调用异常;deque仍只保存已消费最后k项。

手动走一遍

a,b,c,d,e,offset2返回a,b;offset−3返回c,d,e。长流tail2总状态最多2项;offset0完全不消费流。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from itertools import islice
from collections import deque


def select(stream,offset):
    if offset>=0:return list(islice(stream,offset))
    return list(deque(stream,maxlen=-offset))

复杂度

前缀O(min(k,n))时间/输出空间;后缀O(n)时间、O(min(k,n))空间。不是两者都O(k)读取。

易错点与追问

容易失分的边界

  • 负offset不能从前往后只读k项就得到尾部。
  • 为验证流足够长而多读一个元素会影响后续消费者,需约定。

继续深挖

  • 需要返回iterator而非列表时,tail是否还能即读即产?
  • 流可暂时无数据但尚未结束,怎样区分暂时空与真正EOF?
✓已复制微信号!