SWE · Coding

TikTok OA 建房:每次插入后返回最长连续整数区间

用区间端点长度连接左右区间,证明只读邻居时为何不会被内部旧长度误导,支持负坐标和重复查询。

题目重点:用区间端点长度连接左右区间,证明只读邻居时为何不会被内部旧长度误导,支持负坐标和重复查询。

题意与假设

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

  • 只插入不删除,坐标可负、可很大;重复建同一位置按no-op处理,这是本文明确的训练政策。
  • 连续表示相邻整数差1;返回每次操作后的全局最长长度。
  • 端点长度索引可以保留内部旧条目,但另用occupied集合判断是否重复。

解题路线

  1. 新位置x未占用时,若x−1已占用,它必是左侧区间的右端点,否则左区间会包含x,矛盾。同理x+1必是右区间左端点。这保证读到的长度是端点真值。
  2. 设左右长度L/R,新合并区间[x−L,x+R]长度L+1+R。把两端点长度更新为新长度,同时记x长度供初次单点和成员判断的说明;全局best只取max不会下降。
  3. 内部旧长度不用逐项刷新,因为今后只会读取某个待插入点的左右邻居,而这些邻居一旦被读取必是现有区间端点。删除会打破这个证明,因此此结构不支持任意拆区间。
  4. occupied和lengths分开,使“记录在dict中”的意义不被误解成当前端点;重复x直接输出旧best,不再次连接,否则会把同一区间重复相加并凭空增长。
  5. 坐标稀疏时不能建max−min大小的数组,哈希索引只存真正插入的坐标。大整数x±1在Python可直接处理;固定机器整数需检查端点溢出。
  6. 若还需返回最长区间,可在size更新best时保存新左右端点,并定义相同长度tie-break。在线删除需平衡树/区间集合等另一结构,而不是修改本代码几行就保证正确。

手动走一遍

插入[1,3,2,2,5,4]:最长长度[1,1,3,3,3,5]。插入2时读1/3的端点长度各1合成[1,3];重复2不变。插入4时左端邻居3提供长度3、右邻居5长度1,得到[1,5]。

Python 参考实现

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

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

"""After each integer-coordinate insertion, return the longest occupied run.
Duplicates are no-ops; zero/negative coordinates are valid.
"""


def longest_house_runs(queries):
    occupied = set()
    lengths = {}
    best = 0
    output = []
    for x in queries:
        if not isinstance(x, int) or isinstance(x, bool):
            raise ValueError("integer coordinate required")
        if x not in occupied:
            left = lengths.get(x - 1, 0)
            right = lengths.get(x + 1, 0)
            size = left + 1 + right
            occupied.add(x)
            lengths[x] = size
            lengths[x - left] = size
            lengths[x + right] = size
            best = max(best, size)
        output.append(best)
    return output

复杂度

每次插入期望O(1),q次总期望O(q),空间O(U)其中U为不同坐标数。哈希最坏界依实现,大整数坐标还包含其位运算和存储成本。

易错点与追问

容易失分的边界

  • 重复建房仍做合并。
  • 逐个更新整个区间造成二次时间。
  • 按最大坐标分配数组。
  • 支持删除却仍相信旧端点证明。

继续深挖

  • 怎样返回最长区间端点?
  • 需要删除房屋如何换结构?
  • 输入坐标重复应报错还是忽略?
  • 如何用并查集作对照实现?
✓已复制微信号!