关于石头移动问题的题解| 豆包MarsCode AI刷题

142 阅读2分钟

石头的移动问题 问题描述: 小S正在玩一个关于石子的游戏,给定了一些石子,它们位于一维数轴的不同位置,位置用数组 stones 表示。如果某个石子处于最小或最大的一个位置,我们称其为端点石子

在每个回合,小S可以将一颗端点石子移动到一个未占用的位置,使其不再是端点石子。游戏继续,直到石子的位置变得连续,无法再进行任何移动操作。

需要求解:移动的最大次数

测试样例

样例1:

输入:stones = [7, 4, 9]
输出:2

样例2:

输入:stones = [6, 5, 4, 3, 10]
输出:3

样例3:

输入:stones = [1, 2, 3, 4, 5]
输出:0

问题分析

我们需要将石子移动到一维数轴上,使得它们的位置变得连续。每次移动只能移动端点石子,即位于最小或最大位置的石子。移动的目标是使石子的位置连续,且移动次数最多。

解决思路

  1. 确定端点石子:首先,我们需要确定哪些石子是端点石子。端点石子是位于数组中最小和最大位置的石子。
  2. 移动端点石子:在每个回合,我们可以选择一个端点石子,将其移动到一个未占用的位置,使其不再是端点石子。我们需要计算每次移动的最佳位置,以确保移动次数最多。
  3. 计算移动次数:我们需要计算移动的最大次数,直到石子的位置变得连续。

详细步骤

  1. 初始化:首先,我们对数组进行排序,以便更容易找到端点石子和计算移动次数。
  2. 计算初始端点石子:确定初始的最小和最大位置的石子。
  3. 模拟移动过程:在每个回合中,选择一个端点石子,将其移动到一个未占用的位置。我们需要确保每次移动后,石子的位置仍然不连续,以便继续移动。
  4. 更新端点石子:每次移动后,更新端点石子的集合,继续下一次移动。
  5. 终止条件:当石子的位置变得连续时,停止移动,记录移动次数。
  6. 值得注意的是,如果只有一块的石头的话,不用移动,直接返回即可。

代码:

import java.util.Arrays;

public class Main {
    public static int solution(int[] stones) {
        int n = stones.length;
        if (n == 1) {
            return 0;
        }
        Arrays.sort(stones);
        int maxMoves = Math.max(stones[n - 1] - stones[1] - n + 2, stones[n - 2] - stones[0] - n + 2);
        return maxMoves;
    }

    public static void main(String[] args) {
        System.out.println(solution(new int[] { 7, 4, 9 }) == 2);
        System.out.println(solution(new int[] { 6, 5, 4, 3, 10 }) == 3);
        System.out.println(solution(new int[] { 1, 2, 3, 4, 5 }) == 0);

    }
}

总结

通过观察移动过程,从而确定如何使地每次移动距离最少,进而达到求解目的。