移动石子直到连续 II
难度:
标签:
题目描述
代码结果
运行时间: 46 ms, 内存: 17.0 MB
/*
* 思路:
* 1. 使用Java Stream API实现排序和计算最大最小移动次数。
* 2. 最大移动次数通过计算从最小位置到最大位置所需的移动次数得到。
* 3. 最小移动次数通过计算将石子移动到连续的位置得到。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
public int[] numMovesStonesII(int[] stones) {
int[] sortedStones = IntStream.of(stones).sorted().toArray();
int n = sortedStones.length;
int maxMoves = sortedStones[n - 1] - sortedStones[0] + 1 - n;
maxMoves -= Math.min(sortedStones[1] - sortedStones[0] - 1, sortedStones[n - 1] - sortedStones[n - 2] - 1);
int minMoves = maxMoves;
int i = 0;
for (int j = 0; j < n; j++) {
while (sortedStones[j] - sortedStones[i] + 1 > n) i++;
minMoves = Math.min(minMoves, n - (j - i + 1));
}
return new int[]{minMoves, maxMoves};
}
}
解释
方法:
首先对石子的位置进行排序,然后分别计算最大移动次数和最小移动次数。最大移动次数是将所有石子移动到一端所需的最大移动次数,可以通过将除了最左端或最右端的石子外的所有石子移动到另一端来实现。最小移动次数的计算稍微复杂一些,需要考虑连续的石子的位置,使用滑动窗口的方法来计算可以放置最多石子的区间,然后根据这个区间来确定最小的移动次数。
时间复杂度:
O(n log n)
空间复杂度:
O(1)
代码细节讲解
🦆
在计算最大移动次数时,公式中的`stones[-1] - stones[1] - n + 2`和`stones[n - 2] - stones[0] - n + 2`是如何得出的?这两个公式代表了什么意义?
▷🦆
为什么在计算最小移动次数时需要使用滑动窗口方法?滑动窗口在这里的作用是什么?
▷🦆
在特殊情况下,为什么当`i - j + 1 == n - 1`且`stones[i] - stones[j] == n - 2`时,最小移动次数被设置为2?这种情况下具体的移动步骤是怎样的?
▷