脑筋急转弯
数学
题目描述
三枚石子放置在数轴上,位置分别为 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
解法
方法一:分类讨论
我们先将 $a, b, c$ 排序,记为 $x, y, z$,即 $x \lt y \lt z$。
接下来分情况讨论:
如果 $z - x \leq 2$,说明 $3$ 个数已经相邻,不用移动,结果为 $[0, 0]$;
否则,如果 $y - x \lt 3$,或者 $z - y \lt 3$,说明有两个数只间隔一个位置,我们只需要把另一个数移动到这两个数的中间,最小移动次数为 $1$;其他情况,最小移动次数为 $2$;
最大移动次数就是两边的数字逐个往中间靠,最多移动 $z - x - 2$ 次。
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
Python3 Java C++ Go TypeScript
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 ]
1
2
3
4
5
6
7
8
9
10
11
12
13 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 };
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14 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 };
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14 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 }
}
1
2
3
4
5
6
7
8
9
10
11
12 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 ];
}
GitHub