先贴一下此题通过的代码(JAVA版本)
import java.util.Arrays;
public class Main {
public static int solution(int[] stones) {
// 1. 对石子位置进行排序
int n = stones.length;
if(n==1) return 0;
Arrays.sort(stones);
int sum = stones[n-1] - stones[0]+1-n;
// 2. 计算相邻石子之间的空位数
int left = stones[1]-stones[0]-1;
int right = stones[n-1] -stones[n-2]-1;
return sum - Math.min(left,right);
}
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);
}
}
此题直接使用右侧AI提供的思路来写是无法通过的,正确的思路如下,参考力扣1040. 移动石子直到连续 II - 力扣(LeetCode)官方题解。
题目给定一个长度无限的数轴和一个长度为 n 的数组 stones,表示 n 颗石子在数轴上的不同位置。每颗石子的索引 i (0 ≤ i < n)对应的位置在 stones[i] 上,其中如果一颗石子的位置是最小或最大值,则该石子被称为端点石子。每次操作时,我们需要将一颗端点石子移动到一个未占用的位置,使得该石子不再是端点石子。如果无法进行操作,则停止。我们的目标是返回从初始状态开始,能够进行的最大操作次数。
最大操作数的计算方式是通过每次将端点石子移动到最近的空位,直到无法继续操作为止。具体步骤如下:
-
初始条件:将
stones数组按升序排序,表示石子在数轴上的位置。若石子已经是连续的,即stones[n-1] - stones[0] + 1 - n == 0,则无法进行任何操作,最大操作数为 0。 -
第一次操作:选择移动
stones[0](最左端的石子)或stones[n-1](最右端的石子)。每次移动都会消除一些空隙:- 如果选择移动
stones[0],则空隙会被填补,stones[1]和stones[0]之间的空隙消失。 - 如果选择移动
stones[n-1],则空隙会被填补,stones[n-1]和stones[n-2]之间的空隙消失。
- 如果选择移动
-
后续操作:无论选择移动哪个端点,之后的操作都会使得石子向空位靠拢。每次移动都消除一个空隙,直到所有石子变得连续。
-
最大操作数计算:
- 如果第一次选择移动
stones[0],则最大操作次数为:stones[n-1] - stones[1] + 1 - (n-1)。这是因为移动后,最左边的两个石子会紧密相邻,接下来会持续填补空隙。 - 如果第一次选择移动
stones[n-1],则最大操作次数为:stones[n-2] - stones[0] + 1 - (n-1)。同理,最右边的两个石子会紧密相邻,接下来也会持续填补空隙。
- 如果第一次选择移动
-
最终结果:最大操作数是上述两种选择中的较大值,即:
max(stones[n−1]−stones[1]+1−(n−1),stones[n−2]−stones[0]+1−(n−1))\text{max}(stones[n-1] - stones[1] + 1 - (n-1), stones[n-2] - stones[0] + 1 - (n-1))
这个值表示从初始状态开始,能够进行的最大操作次数。