0%

4.30每日

1033. 移动石子直到连续

三枚石子放置在数轴上,位置分别为 abc

每一回合,你可以从两端之一拿起一枚石子(位置最大或最小),并将其放入两端之间的任一空闲位置。形式上,假设这三枚石子当前分别位于位置 x, y, zx < y < z。那么就可以从位置 x 或者是位置 z 拿起一枚石子,并将该石子移动到某一整数位置 k 处,其中 x < k < zk != y

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

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

示例 1:

输入:a = 1, b = 2, c = 5
输出:[1, 2]
解释:将石子从 5 移动到 4 再移动到 3,或者我们可以直接将石子移动到 3。

题解

我们先将 a,b,c 排序,记为 x,y,z, 即 x<y<z。

接下来分情况讨论:

如果 z−x≤2,说明 3 个数已经相邻,不用移动,结果为 [0,0];
否则,如果 y−x<3,或者 z−y<3,说明有两个数只间隔一个位置,我们只需要把另一个数移动到这两个数的中间,最小移动次数为 1;其他情况,最小移动次数为 2;
最大移动次数就是两边的数字逐个往中间靠,最多移动 z−x−2 次。
最后将最小移动次数、最大移动次数返回即可。

class Solution {
public:
    vector numMovesStones(int a, int b, int c) {
        int x = min({a, b, c});
        int z = max({a, b, c});
        int y = a + b + c - x - z;
        int mi = 0, mx = 0;
        if (z - x > 2) {
            mi = y - x < 3 || z - y < 3 ? 1 : 2;
            mx = z - x - 2;
        }
        return {mi, mx};
    }
};