leetcode
leetcode 951 ~ 1000
移动石子直到连续 II

移动石子直到连续 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`是如何得出的?这两个公式代表了什么意义?
这两个公式用于计算将所有石子移动到一端所需的最大移动次数。公式`stones[-1] - stones[1] - n + 2`表示将除最右端石子外的所有石子移动到左端所需的最大移动次数,计算方式是取最右端石子与第二个石子之间的距离,减去除第一个和最后一个石子外的石子数量,再加上2。这是因为我们需要将这段距离变为连续的,每次移动可以将一个石子放在当前最远的石子旁边。同理,公式`stones[n - 2] - stones[0] - n + 2`表示将除最左端石子外的所有石子移动到右端所需的最大移动次数,计算方式相似,只是从另一端进行。
🦆
为什么在计算最小移动次数时需要使用滑动窗口方法?滑动窗口在这里的作用是什么?
滑动窗口方法用于找到一段最长的连续区间,这个区间内最多可以放置石子。通过计算这样的区间,可以确定需要最小移动次数,以使所有石子连续。在滑动窗口中,我们会尝试将窗口扩展到最大,使得窗口内的石子尽可能多,同时窗口的长度不超过石子总数。这样,窗口外剩余的石子数量就是至少需要移动的次数。这种方法有效地帮助我们找到最优移动策略,确保石子数量最大化地使用给定的空间。
🦆
在特殊情况下,为什么当`i - j + 1 == n - 1`且`stones[i] - stones[j] == n - 2`时,最小移动次数被设置为2?这种情况下具体的移动步骤是怎样的?
当`i - j + 1 == n - 1`且`stones[i] - stones[j] == n - 2`时,意味着除一个石子外,所有石子几乎形成了一个连续序列,但是有一个长度为2的空隙。在这种情况下,我们无法通过一步移动来填补这个空隙,因此最小移动次数设置为2。具体的移动步骤通常是将两端中的一个石子移动到这个空隙中的一端,然后将另一个石子移动到空隙的另一端,或者根据具体位置可能需要将一端的石子依次移动来填补这个空隙。这样的操作确保所有石子都能连续排列。

相关问题