数学 
      
    
      
      
      
        脑筋急转弯 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
    
题目描述 
三枚石子放置在数轴上,位置分别为 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