石子移动问题解题思路 | 豆包MarsCode AI刷题

2 阅读4分钟

代码思路

  1. 排序石子位置:首先对石子位置进行排序,这样可以更容易地计算石子之间的间隔。
  2. 计算间隔:计算相邻石子之间的间隔,这些间隔将帮助你确定可以移动的最大次数。
  3. 计算最大移动次数:根据题目要求,计算可以移动的最大次数。

代码实现


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:无需移动

代码详解

. 函数定义

def solution(stones: list) -> int:

这段代码定义了一个名为 solution 的函数,它接受一个列表 stones 作为参数,列表中的元素应该是表示石子位置的数值,并且函数会返回一个整数类型的结果。

2. 对石子位置排序

stones.sort()
n = len(stones)
  • 首先,对输入的 stones 列表进行排序操作。排序的目的是为了后续能够方便地按照顺序来分析石子之间的位置关系,以便计算需要移动石子的次数。
  • 然后,通过 len(stones) 获取列表 stones 中元素的个数,并将其赋值给变量 n,用于后续的计算和判断。

3. 特殊情况处理:石子数少于等于 1

if n <= 1:
    return 0

这里判断如果输入的 stones 列表中的元素个数小于等于 1,这意味着要么没有石子,要么只有一颗石子,在这种情况下,显然不需要移动任何石子就能使它们 “连续”(因为本身就已经是一种特殊的连续状态了),所以直接返回 0,表示移动次数为 0。

4. 计算最大移动次数

max_moves = max(stones[-1] - stones[1] - (n - 2), stones[-2] - stones[0] - (n - 2))

这是代码的核心计算部分,用于确定要使所有石子连续所需的最大移动次数。

  • 计算思路是分别考虑以最左端石子和最右端石子为固定点的两种情况:

    • 当以最左端石子为固定点时,需要关注最右端石子与它的相对位置关系。此时,理想的连续状态下,除了最左端石子外,其他 n - 1 颗石子应该紧密排列在它右侧,相邻两颗石子的间距应该为 1。所以,右侧需要填补的空隙数量可以通过 stones[-1](最右端石子的位置)减去 stones[1](从左数第二颗石子的位置,因为最左端石子位置固定了,这里关注它右侧第一颗石子的相对位置),再减去 n - 2(除去最左端石子后,剩下 n - 1 颗石子紧密排列应该占据的位置长度)来计算。
    • 同理,当以最右端石子为固定点时,通过 stones[-2](从右数第二颗石子的位置,因为最右端石子位置固定了,这里关注它左侧第一颗石子的相对位置)减去 stones[0](最左端石子的位置),再减去 n - 2 来计算左侧需要填补的空隙数量。
  • 最后,使用 max 函数取上述两种情况计算结果中的最大值,这个最大值就是要使所有石子连续所需的最大移动次数,并将其赋值给变量 max_moves

5. 返回结果

return max_moves

将计算得到的最大移动次数 max_moves 作为函数的结果返回。

6. 测试用例部分

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:无需移动
  • 在这段代码中,当脚本作为主程序运行(即 __name__ == '__main__' 条件成立)时,会执行以下操作:

    • 分别调用 solution 函数并传入不同的测试用例数据(如 [7, 4, 9][6, 5, 4, 3, 10][1, 2, 3, 4, 5]),然后将函数返回值与预期的移动次数进行比较,并将比较结果(True 或 False)打印输出。这些测试用例用于验证 solution 函数在不同输入情况下是否能正确计算出使石子连续所需的移动次数。

总体而言,这段代码实现了一个功能,即根据输入的表示石子位置的列表,计算出要使所有石子连续排列所需的最大移动次数,并通过测试用例对函数的正确性进行了简单验证。