题目重点:从0走向target,找到最近未经过的右侧滑板车,骑最多10距离,累计骑行而非总路程。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 只向右移动,从0开始,最近设备允许在当前位置;到达target立即结束。每辆最多骑capacity=10,步行距离不计入答案。
- 已骑过的后方设备不能折返拿,不能停在半路改骑更近设备;题面若允许中途换车或充电,另定规则。
- 输入设备位置非负,可无序;同位置多个设备是不同实体,但第一次骑行后其余已在后方。
解题路线
- 位置排序,扫描每辆s:s<position表示已越过,跳过;s>=target用不到。其他情况先步行到s,再骑min(capacity,target−s),累计这部分距离。
- 一次骑行跨过多个设备,它们不能再次使用,否则会虚增骑行。位置只前进且每设备至多检查一次。
- 返回骑行总长度而不是坐标终点;没有设备时仍能步行到终点,但答案0。
手动走一遍
target=25,设备[2,5,18]:先步行2骑到12,设备5已越过;再步行18骑到25,骑行10+7=17。[30]不在终点之前,答案0。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def scooter_distance(target, scooters, capacity=10):
"""Travel from 0 rightward; use first scooter at or ahead of position; ride to target or empty.
Passed scooters cannot be collected backward. Repeated positions are distinct scooters,
but a scooter at the same position is passed once the current ride moves beyond it.
"""
if target < 0 or capacity <= 0 or any(s < 0 for s in scooters):
raise ValueError("nonnegative route and positive capacity required")
position = ridden = 0
for s in sorted(scooters):
if position >= target:
break
if s < position or s >= target:
continue
position = s
ride = min(capacity, target-position)
ridden += ride
position += ride
return ridden
复杂度
O(n log n)排序,扫描O(n),O(n)排序副本空间;已排序输入可O(n)时间、O(1)额外状态。
易错点与追问
容易失分的边界
- 把每车固定加10会在靠近终点处超计。
- 设备排序后不检查已越过位置,会在同一段路反复计数。
继续深挖
- 若要最少步行且可中途换车,变成不同优化问题;原题的固定“骑至耗尽”贪心轨迹不再适用。
- 当每车capacity不同,仍按固定规则模拟,当前位置由该车容量更新;充电循环题需要额外时间状态。
