LeetCode【1040】移动石子直到连续 II

在一个长度无限的数轴上,第 i 颗石子的位置为 stones[i]。如果一颗石子的位置最小/最大,那么该石子被称作端点石子。

每个回合,你可以将一颗端点石子拿起并移动到一个未占用的位置,使得该石子不再是一颗端点石子。

值得注意的是,如果石子像 stones = [1,2,5] 这样,你将无法移动位于位置 5 的端点石子,因为无论将它移动到任何位置(例如 0 或 3),该石子都仍然会是端点石子。

当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。

要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves] 。

示例 1:

输入:[7,4,9]
输出:[1,2]
解释:
我们可以移动一次,4 -> 8,游戏结束。
或者,我们可以移动两次 9 -> 5,4 -> 6,游戏结束。

示例 2:

输入:[6,5,4,3,10]
输出:[2,3]
解释:
我们可以移动 3 -> 8,接着是 10 -> 7,游戏结束。
或者,我们可以移动 3 -> 7, 4 -> 8, 5 -> 9,游戏结束。
注意,我们无法进行 10 -> 2 这样的移动来结束游戏,因为这是不合要求的移动。

示例 3:

输入:[100,101,104,102,103]
输出:[0,0]

提示:

3 <= stones.length <= 10^4
1 <= stones[i] <= 10^9
stones[i] 的值各不相同。

分析

移动最多的次数:
以[7,4,9]为例,按大小排在数轴
4,,7,_,9
此时可以移动的只有4、9,而且移动位置不能为边界,分析:
1、若想移动的最远(留的缝隙最多),肯定是将9移动到5的位置,因为4-7中间的空隙最多,将9移动过去中间的缝隙最多,可移动的次数才有可能最多。
2、将9移动到左侧缝隙后,从7-9之间的缝隙将变得没有作用,因为移动石子,不能移动到边界
3、最终移动完要形成一个连续的数字串,也就是说任何空隙都意味着一次移动
综上,最大的移动次数为:总空隙数-min(左空隙,右空隙)

代码

public int[] numMovesStonesII(int[] stones) {
       Arrays.sort(stones);
        int i = 0, n = stones.length;
        int minnerSpace = Math.min(stones[n - 1] - stones[n - 2] - 1, stones[1] - stones[0] - 1);
        int maxMove = (stones[n - 1] - stones[0] - n + 1) - minnerSpace;
        int minMove = stones.length;
        for (int j = 0; j < n; j++) {
            while (stones[j] - stones[i] + 1 > n)
                i++;
            if (j - i == stones[j] - stones[i] && n - (j - i + 1) == 1)
                minMove = Math.min(2, minMove);
            else
                minMove = Math.min(minMove, n - (j - i + 1));
        }
        return new int[]{minMove, maxMove};
    }
发布了55 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq422243639/article/details/98629945