三枚石子放置在数轴上,位置分别为 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 <= a <= 100
1 <= b <= 100
1 <= c <= 100
a != b, b != c, c != a
方法一:分类讨论
我们先将
接下来分情况讨论:
- 如果
$z - x \leq 2$ ,说明$3$ 个数已经相邻,不用移动,结果为$[0, 0]$ ; - 否则,如果
$y - x \lt 3$ ,或者$z - y \lt 3$ ,说明有两个数只间隔一个位置,我们只需要把另一个数移动到这两个数的中间,最小移动次数为$1$ ;其他情况,最小移动次数为$2$ ; - 最大移动次数就是两边的数字逐个往中间靠,最多移动
$z - x - 2$ 次。
时间复杂度
class Solution:
def numMovesStones(self, a: int, b: int, c: int) -> List[int]:
x, z = min(a, b, c), max(a, b, c)
y = a + b + c - x - z
mi = mx = 0
if z - x > 2:
mi = 1 if y - x < 3 or z - y < 3 else 2
mx = z - x - 2
return [mi, mx]
class Solution {
public int[] numMovesStones(int a, int b, int c) {
int x = Math.min(a, Math.min(b, c));
int z = Math.max(a, Math.max(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 new int[] {mi, mx};
}
}
class Solution {
public:
vector<int> 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};
}
};
func numMovesStones(a int, b int, c int) []int {
x := min(a, min(b, c))
z := max(a, max(b, c))
y := a + b + c - x - z
mi, mx := 0, 0
if z-x > 2 {
mi = 2
if y-x < 3 || z-y < 3 {
mi = 1
}
mx = z - x - 2
}
return []int{mi, mx}
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
function numMovesStones(a: number, b: number, c: number): number[] {
const x = Math.min(a, Math.min(b, c));
const z = Math.max(a, Math.max(b, c));
const y = a + b + c - x - z;
let mi = 0,
mx = 0;
if (z - x > 2) {
mi = y - x < 3 || z - y < 3 ? 1 : 2;
mx = z - x - 2;
}
return [mi, mx];
}