旋转数组中的最小数字

1:采用二分法解答这个问题,

mid = low + (high - low)/2
需要考虑三种情况:
 
 

1.array[low]>array[high] :  用两个指针来操作: 相当于二分法   低位指针在第一个递增序列内;高位指针在第二个递增序列内;

   (1)array[low]<array[mid] :
   出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
 
  low = mid + 1
  (2)array[low]>array[mid] :
  出现这种情况的array类似[5,1,2,3,4],此时最小数字一定就是array[mid]或者在mid的左
  边。因为右边必然都是递增的。
  high = mid

 (3)循环的终止条件为: high-low==1; 因为到了两个指针相邻的地方,那么其实high 所对应的值即是最小值

 
 

2.array[low]<array[high] : //其实就是相当于将 一个本来的递增数列 后面0 个值旋转到前面去;  还是递增数列;第一个值为最小值

3 .array[low]==array[mid] == array[low]:  //注意题目 这是个非递减   没说一定递增

出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边还是右边,这时只好一个一个试 ,
只能单独列出来  用顺序查找的方法来找到最小值;
 
class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
       if(rotateArray.empty())
       return 0; 
       //第一种情况 全是递增 后面比前面大 两个指针操作 【12345】
       //第二种情况 有可能相等的递增 【01111】 [11101]
       //第三种情况 递增数 只把后面0个转到前面来
      int low=0;
      int high=rotateArray.size()-1;  
      int mid=0; 
        while(rotateArray.at(low)>=rotateArray.at(high))
        {
           if (high-low==1) 
           {
             return  rotateArray.at(high);
           }
           mid=(low+high)/2;
          //第二种情况  三个都相等
           if (rotateArray.at(low)==rotateArray.at(mid)&&rotateArray.at(low)==rotateArray.at(high))
            return order(rotateArray);//去顺序查找
               
               
            if(rotateArray.at(low)<=rotateArray.at(mid))//注意 有等于号
               low=mid; 
           else if(rotateArray.at(low)>=rotateArray.at(mid))
                high=mid;
        }
        return rotateArray.at(low);

    }
               
   public:
    int order(vector<int> rotateArray) 
    {
        int SIZE=rotateArray.size();
        int min=rotateArray.at(0);
        for (int i=0;i<SIZE;i++)
        {
         if (rotateArray.at(i)<min)
             min=rotateArray.at(i);
        }
          
        return min;
    }
             
};

 

 

 
posted @ 2019-08-18 12:08  高颖1995  阅读(131)  评论(0编辑  收藏  举报