旋转数组的最小数字

题目描述:

  把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

算法描述:

  如果从头到尾进行扫描的话,时间复杂度为O(n),但这种方法过于简单,我们需要找出更加快捷的方法来解决这个问题。于是想到了二分查找。我们可以定义两个指针分别指向数组的头和尾,这样去扫描数组,利用二分查找的机制,首先找到数组中的中中间值,如果中间值比开头的值大则将这个中间值得指针付给这个开头指针,同理如果中间值得值小于尾部的值,则将中间值得指针赋值给尾部指针。总体的思想是这样的。

算法实现:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int searchMin(int *data, int length){
 5     if(data == NULL || length < 0){
 6         return 10000;
 7     }
 8     /*初始化一些值 */
 9     int index1 = 0; 
10     int index2 = length - 1;
11     int index = index1;
12 /*核心算法*/
    /* 情况1,数组初始时就是有序的 */
   if(data[index1] <= data[index2]){
      return data[index1];
    }
  
  /*如果是旋转数组*/
13     while(data[index1] >= data[index2]){
    /*如果两个指针的距离差1则找到了,就是index2
14 if(index2 - index1 == 1){ 15 index = index2; 16 break; 17 } 18 19 index = (index1 + index2) / 2; 20 /*情况2,如果三个指针指向的数字值相同,只能扫描 21 if(data[index1] == data[index2] && data[index1] == data[index]){ 22 23 int min = data[index1]; 24 for(int i = 0; i < length; i++){ 25 if(min > data[i]){ 26 min = data[i]; 27 } 28 } 29 30 return min; 31 } 32 33 if(data[index] >= data[index1]){ 34 index1 = index; 35 } 36 37 if(data[index] <= data[index2]){ 38 index2 = index; 39 } 40 } 41 42 return data[index]; 43 } 44 45 int main(){
     int str[] = {1, 2, 3, 4, 5}; //情况1
46 // int str[] = {4, 5 , 6, 7, 8, 1, 2, 3}; //旋转数组 47 // int str[] = {1, 1, 1, 0, 1, 1, 1, 1, 1}; //情况2 48 // int *str = NULL; //特殊情况 49 int len = sizeof(str) / sizeof(int); 50 51 int result = searchMin(str, len); 52 if(result == 10000){ 53 cout<<"the invalid result"<<endl; 54 } 55 else{ 56 cout<<"the result is: "<<result<<endl; 57 } 58 return 0; 59 }
原文地址:https://www.cnblogs.com/dormant/p/5322925.html