题目分析
石子移动问题要求找到石子位置连续所需的最大移动次数。题目描述的核心是:
- 石子的位置连续:意味着在数轴上没有任何间隙,石子位置从
min(stones)到max(stones)恰好形成一个连续的区间。 - 端点石子:当前位于最左或最右的石子,因其位置最为边缘,可以在每回合被移动到其他未被占用的位置。
问题求解
为了实现石子位置的连续化,我们需要:
- 每次将端点石子移动到数轴上的某个空位。
- 计算所需的最大移动次数。
通过分析可知,最大移动次数直接与石子分布的间隔有关。如果间隔很大,就需要较多次移动才能填充这些空隙。
解题思路
- 排序:将石子的初始位置排序,方便计算连续性。
- 计算最大移动次数:
- 假设固定左端或右端,计算中间区域需要多少步才能连续。
- 取两种情况下的最大值。
代码实现
以下是解题代码及说明:
def solution(stones: list) -> int:
# 对石子位置排序,确保可以顺序处理
stones.sort()
n = len(stones)
# 如果石子数少于等于1,则不需要移动
if n <= 1:
return 0
# 最大移动次数计算:
# 1. 以最左端石子为固定点,计算右侧需要填补的空隙
# 2. 以最右端石子为固定点,计算左侧需要填补的空隙
max_moves = max(stones[-1] - stones[1] - (n - 2), stones[-2] - stones[0] - (n - 2))
return max_moves
# 测试用例
if __name__ == '__main__':
print(solution(stones=[7, 4, 9]) == 2) # 测试例1:两步使石子连续
print(solution(stones=[6, 5, 4, 3, 10]) == 3) # 测试例2:三步使石子连续
print(solution(stones=[1, 2, 3, 4, 5]) == 0) # 测试例3:无需移动
示例分析
示例1
输入:
stones = [7, 4, 9]
排序后:
[4, 7, 9]
计算最大移动:
- 固定左端点
4,需要填补7和9之间的空隙,共2步。 - 固定右端点
9,需要填补4和7之间的空隙,共2步。
返回 2。
示例2
输入:
stones = [6, 5, 4, 3, 10]
排序后:
[3, 4, 5, 6, 10]
计算最大移动:
- 固定左端点
3,需要填补10和6之间的空隙,共3步。 - 固定右端点
10,需要填补3和6之间的空隙,共3步。
返回 3。
示例3
输入:
stones = [1, 2, 3, 4, 5]
排序后:
[1, 2, 3, 4, 5]
计算最大移动:
- 不需要任何移动,因为已经连续。
返回 0。
复杂度分析
-
时间复杂度:
- 排序操作需要 (O(n \log n)),是主要的计算量。
- 其他计算如间隔和最大值的比较是 (O(1))。
- 综合复杂度为 (O(n \log n))。
-
空间复杂度:
- 仅使用了常量级额外空间,复杂度为 (O(1))。
总结
该问题通过排序、间隔计算即可求解,主要考察的是理解最大间隙的计算方法。代码清晰简洁,适用于多种场景。