剑指Offer-旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}{1,2,3,4,5}的一个旋转,该数组的最小值为1
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0

如果直接遍历数组,时间复杂度为On,可以利用旋转数组的特性来解决此题;

思路:

(1)如果发生旋转,前面的数至少去了一个放在数组的后面;

     1)旋转后,数组分为两个排序数组,而且前一个数组中的数均大于等于后一个数组中的数,因为要查找数组中的最小数,也就是第二个数组中的第一个数,可以采用二分查找的思想;

2)设置两个指针p1,p2p1指向数组的开始位置,也就是第一个数组的开始位置,p2指向数组的终止位置,也就是第二个数组的结束位置。Mid=p1+p2/2;

   如果中间位置mid的数大于p1指向的数,则mid在第一个数组中,让p1指向mid所指向的数,p1指向的依然是数组1的数;

   如果中间位置mid的数小于p2所指向的位置,则mid在第二个数组中,p2指向mid指向的数,p2指向的依然是数组2的数;

Mid不是指向数组1的数,就是指向数组2的数,指向数组1的数,就让p1移动到mid的位置,指向数组2就让p2数组移动到mid的位置;直到p2移动到数组1的结束的位置,p1移动到数组2的开始的位置,此时p2p1挨着,而且p1所指向的数组2的起始位置中存放的就是最小数;

2如果中间位置的数既等于p1位置数,又等于p2位置的数,这时候,不能确定移哪个指针,就必须采用顺序查找的方法来寻找最小数;

 

总结:此题就是利用两个指针,一个往后移,一个往前移,具体怎么移,通过mid的大小控制;直到两个指针的位置挨着,就可以找到最小数了!

还需要考虑:

如果数组取0个放在了数组的后面,也就是排序数组没有变,这时p1指向的数小于p2指向的数;直接是数组的首元素是最小的数;

[java]  view plain  copy
  1. import java.util.ArrayList;  
  2. public class Solution {  
  3.     public int minNumberInRotateArray(int [] array)   
  4.     {  
  5.           if(array == null || array.length == 0)  
  6.        {  
  7.            return 0;  
  8.        }  
  9.        int p1 = 0;//从前往后走  
  10.        int p2 = array.length-1;//从后往前走  
  11.        int min = array[p1];//如果没发生旋转,直接将array[0]的值返回,  
  12.        int mid = 0;  
  13.        //当数组发生旋转了,  
  14.        while(array[p1] >= array[p2])  
  15.        {  
  16.            //当两个指针走到挨着的位置时,p2就是最小数了  
  17.            if(p2 - p1 == 1)  
  18.            {  
  19.                min = array[p2];  
  20.                break;  
  21.            }  
  22.            mid = (p1 + p2)/2;   
  23.            //如果中间位置的数既等于p1位置的数又等于P2位置的数  
  24.            if(array[p1] == array[mid]&&array[p2]==array[mid])  
  25.            {  
  26.               min = minInorder(array,p1,p2);  
  27.            }  
  28.          if(array[p1] <= array[mid])//若中间位置的数位于数组1,让p1走到mid的位置  
  29.          {  
  30.              p1 = mid;  
  31.          }  
  32.          else if(array[p2] >= array[mid])//若中间位置的数位于数组2,让p2走到mid的位置  
  33.          {  
  34.              p2 = mid;  
  35.          }  
  36.        }  
  37.        return min;  
  38.    }  
  39.    private int minInorder(int[]array,int p1,int p2)  
  40.    {  
  41.        int min = array[p1];  
  42.        for (int i = p1 + 1; i <= p2; i++)  
  43.     {  
  44.         if(min > array[i])  
  45.         {  
  46.             min = array[i];  
  47.         }  
  48.     }  
  49.        return min;  
  50.    }  
  51.       
  52. }  

你可能感兴趣的:(剑指Offer-旋转数组的最小数字)