
本文详解如何将暴力多遍历的座位距离算法重构为高效单次扫描方案,通过巧妙利用首次人位索引与连续空位间距计算,在 o(n) 时间、o(1) 空间内精准求解最大最小距离,并提升代码可读性与鲁棒性。
本文详解如何将暴力多遍历的座位距离算法重构为高效单次扫描方案,通过巧妙利用首次人位索引与连续空位间距计算,在 o(n) 时间、o(1) 空间内精准求解最大最小距离,并提升代码可读性与鲁棒性。
在解决「最大化到最近人的距离」问题时,核心目标是:给定一个仅含 0(空座)和 1(有人)的数组,找出一个空位,使得该位置到最近已坐人位置的距离最大,并返回这个最大距离。
原始实现虽逻辑可行,但存在明显冗余:它分别用三个独立循环处理左端连续空位、右端连续空位及中间最大连续空段,还额外引入了 curr_count/max_count 等状态变量,导致逻辑分散、边界判断繁杂、可读性低,且对 max_count 的 (max_count + 1) // 2 计算未明确体现其几何含义(即两个相邻人之间最优落点必在中点,距离为间隔长度的一半向下取整)。
更优解法采用单次正向扫描 + 关键状态复用策略,仅需一次遍历即可覆盖全部三种场景(左端、中间、右端),代码简洁且语义清晰:
from typing import List
class Solution:
def maxDistToClosest(self, seats: List[int]) -> int:
# 找到第一个有人的位置,作为初始参考点 p
p = seats.index(1)
# c 表示当前找到的最大“到最近人的距离”,初始值设为 p(即坐在最左端时到第一个人的距离)
c = p
# 从 p+1 开始遍历剩余座位
for i in range(p + 1, len(seats)):
if seats[i] == 1:
# 当前位置 i 有人 → 更新 c:i 与上一个位置 p 之间的中点距离为 (i - p) // 2
c = max(c, (i - p) // 2)
p = i # 更新上一个有人位置
# 处理右端边界:若末尾是空座,则最右空位到 p 的距离为 len(seats) - 1 - p
# 注意:此处用 `if seats[-1] else ...` 是判断末尾是否为空(seats[-1] == 0 → 条件为 False)
return c if seats[-1] == 1 else max(c, len(seats) - 1 - p)✅ 关键优化点解析:
- 单次遍历:避免重复扫描,时间复杂度稳定为 O(n),空间复杂度 O(1);
- 语义化变量命名:p(previous person index)、c(current max distance)直观表达意图;
- 统一数学模型:中间最优距离由 (i - p) // 2 直接得出,本质是区间 [p, i] 内任意空位 x 到两端人的最小距离 min(x−p, i−x) 的最大值,其理论最大值恰在中点,结果为 ⌊(i−p)/2⌋;
- 边界处理优雅:左端距离直接用首个 1 的索引 p 表示(即 0 到 p 全空);右端则用 len(seats) - 1 - p 计算,无需额外反向循环;
- 类型提示与健壮性:添加 List[int] 类型注解,明确输入约束;末尾判断显式写为 seats[-1] == 1,比原答案中 if seats[-1] 更清晰(避免布尔上下文歧义)。
⚠️ 注意事项:
- 题目保证至少有一个 1 和一个 0,因此 seats.index(1) 必然成功,无需异常捕获;
- 整数除法 // 在 Python 中自动向下取整,完美匹配题意(如间隔 5 个空位 00000 夹在两个 1 之间,最优距离为 5 // 2 = 2);
- 不要误将右端距离写成 len(seats) - p —— 正确应为 len(seats) - 1 - p(索引从 0 开始)。
该实现不仅性能更优,更体现了算法设计中“状态驱动”与“几何直觉”的结合:把抽象的距离最大化问题,转化为对三个典型区间的线性归纳,是典型「一次遍历 + 分类讨论」范式的优秀实践。










