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

101 阅读3分钟

石子移动问题解析

问题描述

小S正在玩一个关于石子的游戏。给定一些石子,它们位于一维数轴的不同位置,位置用数组 stones 表示。如果某个石子处于最小或最大的一个位置,我们称其为端点石子。在每个回合,小S可以将一颗端点石子移动到一个未占用的位置,使其不再是端点石子。游戏继续,直到石子的位置变得连续,无法再进行任何移动操作。你需要帮助小S找到可以移动的最大次数。

难度:中

核心问题

核心问题是通过移动端点石子,使得所有石子的位置变得连续,即不存在任何两个相邻石子之间有空位。目标是计算达到这一目标所需的最大移动次数。

解题思路

  1. 排序:首先对石子的位置数组进行排序,以便于后续操作。
  2. 计算跨度:定义一个辅助函数 ll(s) 来计算当前石子分布的最大跨度,即最大位置与最小位置之间的差值加一。
  3. 贪心策略:由于最终目标是计算最大移动次数,因此每次选择能够产生更大影响的端点石子进行移动。具体来说,比较去除第一个石子后与去除最后一个石子后的剩余石子最大跨度,选择导致跨度更大的那一个端点石子进行移动。
  4. 插入新石子:在距离端点最近的 “空位置” 插入新的石子,以填补空隙。
  5. 终止条件:当所有石子的位置变得连续时,即当前的跨度等于石子的数量时,停止移动。

主要逻辑

  1. 初始化:对石子位置数组进行排序,并初始化移动次数 number 为0。
  2. 循环移动:在当前石子分布的最大跨度大于石子数量时,继续移动石子。
    • 计算去除第一个石子后和去除最后一个石子后的剩余石子最大跨度。
    • 选择导致跨度更大的端点石子进行移动。
    • 在适当的位置插入新的石子,以填补空隙。
    • 更新移动次数 number
  3. 返回结果:当所有石子的位置变得连续时,返回移动次数 number

代码实现

def solution(stones: list) -> int:
    # 对石子位置数组进行排序
    sort_list = sorted(stones)
    number = 0
    
    # 定义辅助函数,计算当前石子分布的最大跨度
    def ll(s):
        return max(s) - min(s) + 1
    
    # 循环移动石子,直到所有石子的位置变得连续
    while ll(sort_list) > len(stones):
        if ll(sort_list[1:]) >= ll(sort_list[:-1]):
            # 移动第一个石子
            sort_list.pop(0)
            for i in range(len(sort_list) - 1):
                if sort_list[i] + 1 < sort_list[i + 1]:
                    sort_list.insert(i + 1, sort_list[i] + 1)
                    number += 1
        else:
            # 移动最后一个石子
            sort_list.pop(-1)
            for i in range(len(sort_list) - 1, -1, -1):
                if sort_list[i] - 1 > sort_list[i - 1]:
                    sort_list.insert(i, sort_list[i] - 1)
                    number += 1
    
    return number

if __name__ == '__main__':
    print(solution(stones=[7, 4, 9]) == 2)
    print(solution(stones=[6, 5, 4, 3, 10]) == 3)
    print(solution(stones=[1, 2, 3, 4, 5]) == 0)

复杂度分析

  • 时间复杂度

    • 排序操作的时间复杂度为 (O(n \log n))。
    • 主要循环的时间复杂度为 (O(n^2)),因为在每次移动操作中,最坏情况下需要遍历整个数组来查找插入位置。
    • 总的时间复杂度为 (O(n^2))。
  • 空间复杂度

    • 排序操作需要 (O(n)) 的额外空间。
    • 其他变量占用的空间是常数级别的,所以总体空间复杂度为 (O(n))。