day113 1033. 移动石子直到连续(Java)

75 阅读2分钟

题目来源: 1033. 移动石子直到连续

题目描述:

  • 描述: 三枚石子放置在数轴上,位置分别为 a,b,c。 每一回合,你可以从两端之一拿起一枚石子(位置最大或最小),并将其放入两端之间的任一空闲位置。形式上,假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z。那么就可以从位置 x 或者是位置 z 拿起一枚石子,并将该石子移动到某一整数位置 k 处,其中 x < k < z 且 k != y。 当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。 要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves]

  • 示例:

示例1:
输入:a = 1, b = 2, c = 5
输出:[1, 2]
  • 解释:将石子从 5 移动到 4 再移动到 3,或者我们可以直接将石子移动到 3。
示例2:
输入:a = 4, b = 3, c = 2
输出:[0, 0]
  • 解释:我们无法进行任何移动。

思路

思路1 可以假设x,y,z 分别为从小到大排序后的a,b,c,来讨论最小和最大移动次数。 当三枚石子连续放置时,即(y−x)=1 并且(z−y)=1,不需要额外移动,最小移动次数为0。 当三枚石子中有两枚是连续放置,或者间隔为1 时,我们只需对另外一枚石子移动一次,最小移动次数为1。 对于其他情况,我们最小需要移动2 次。 对于最多移动次数,我们可以考虑将x 向右(增加1),或者将z 向左(减小1),每次移动都会使得两侧的距离减小1,所以最多可以移动z−x−2 次。

具体实现1

class Solution {
    public int[] numMovesStones(int a, int b, int c) {
        int x = Math.min(Math.min(a, b), c);
        int z = Math.max(Math.max(a, b), c);
        int y = a + b + c - x - z;

        int[] res = new int[2];
        res[0] = 2;
        if (z - y == 1 && y - x == 1) {
            res[0] = 0;
        } else if (z - y <= 2 || y - x <= 2) {
            res[0] = 1;
        }
        res[1] = z - x - 2;
        return res;
    }
}

复杂度分析1:

  • 时间复杂度:O(1)O(1)

  • 空间复杂度:O(1)O(1)