
本文详解如何用单次遍历、更简洁逻辑重构原始代码,显著提升可读性与效率,同时正确处理边界空座情况。
本文详解如何用单次遍历、更简洁逻辑重构原始代码,显著提升可读性与效率,同时正确处理边界空座情况。
在解决「到最近乘客的最大距离」(leetcode 849)问题时,核心目标是:给定一个仅含 0(空座)和 1(有人)的数组,找出一个空位,使它到最近已坐人位置的距离最大化,并返回该最大距离。
原始实现虽功能正确,但存在明显可优化点:
- 使用了三次独立遍历(左端连续空座、右端连续空座、中间最长连续空座);
- 变量命名模糊(如 left_max, curr_count, max_count),语义不清晰;
- 中间段逻辑未区分「连续空座长度」与「实际可获得的最大最小距离」(即 (gap + 1) // 2);
- 边界处理冗余(如手动 while 循环统计首尾零),易出错且缺乏健壮性。
✅ 优化思路:一次扫描,三类场景统一建模
我们只需记录上一个 1 的位置 p,并在遇到下一个 1 时,计算二者之间的中点距离(即 (i – p) // 2),该值即为这段中间空区间内能获得的最大最小距离。同时,首尾两种边界情况需单独考虑:
- 左边界:首个 1 前的所有空位 → 距离为 p(即索引值);
- 右边界:末位 1 后的所有空位 → 距离为 len(seats) – 1 – p;
- 中间区间:任意两个相邻 1 之间 → 最优落点在正中,距离为 (i – p) // 2。
以下为优化后的 Python 实现(使用类型提示增强可读性,逻辑高度凝练):
from typing import List class Solution: def maxDistToClosest(self, seats: List[int]) -> int: # 找到第一个 1 的位置,作为初始参考点 p p = seats.index(1) # c 记录当前全局最大「到最近人的距离」 c = p # 初始化为左边界距离(即第一个 1 到开头的距离) # 从 p+1 开始遍历,寻找后续的 1 for i in range(p + 1, len(seats)): if seats[i] == 1: # 当前 1 与上一个 1 的距离为 (i - p),最优距离为中点 → (i - p) // 2 c = max(c, (i - p) // 2) p = i # 更新上一个 1 的位置 # 处理右边界:最后一个 1 到末尾的距离 c = max(c, len(seats) - 1 - p) return c
? 关键改进说明:
- ✅ 单次遍历完成全部逻辑:无需预扫描首尾,也无需额外循环统计中间段;
- ✅ 变量语义明确:p 恒为上一个已知 1 的下标,c 始终代表当前最优解;
- ✅ 边界自然覆盖:seats.index(1) 确保 p 合法;末尾 max(c, len(seats)-1-p) 统一处理右边界;
- ✅ 数学严谨:(i – p) // 2 正确给出两 1 之间最大最小距离(例如 [1,0,0,0,1] → i-p=4 → 4//2=2)。
? 注意事项:
- 输入保证至少有一个 1 和一个 0,因此 seats.index(1) 安全;
- 整数除法 // 在 Python 中自动向下取整,恰好满足 (gap + 1) // 2 的等价效果(因 gap = i – p 为偶数或奇数时,(i-p)//2 与 (gap+1)//2 数值一致);
- 时间复杂度:O(n);空间复杂度:O(1) —— 达到理论最优。
? 总结:算法优化不只关乎性能,更是对问题本质的提炼。本解法将“找最大最小距离”抽象为对三种几何场景(左/中/右)的统一距离建模,用最少的状态维护和最清晰的控制流,实现了正确性、可读性与效率的三重提升。