剑指offer——面试题11:旋转数组的最小数字

 1 #include"iostream"
 2 using namespace std;
 3 
 4 int GetMinNumber(int *data,int len)
 5 {
 6     int left=0,right=len-1,mid;
 7 
 8     while(left<right-1)
 9     {
10         mid=(left+right)/2;
11         if(data[mid]>=data[left])
12             left=mid;
13         else if(data[mid]<data[right])
14             right=mid;
15     }
16     return data[right];
17 }
18 
19 void Test1()
20 {
21     cout<<"Test1:";
22     int data[]={3,4,5,1,2};
23     if(GetMinNumber(data,5)==1)
24         cout<<"passed."<<endl;
25     else
26         cout<<"failed."<<endl;
27 }
28 
29 void Test2()
30 {
31     cout<<"Test2:";
32     int data[]={3,4,5,6,1,2};
33     if(GetMinNumber(data,6)==1)
34         cout<<"passed."<<endl;
35     else
36         cout<<"failed."<<endl;
37 }
38 
39 void Test3()
40 {
41     cout<<"Test3:";
42     int data[]={2,1};
43     if(GetMinNumber(data,2)==1)
44         cout<<"passed."<<endl;
45     else
46         cout<<"failed."<<endl;
47 }
48 
49 int main()
50 {
51     Test1();
52     Test2();
53     Test3();
54     return 0;
55 }
View Code

官方答案:

  1 // 面试题11:旋转数组的最小数字
  2 // 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
  3 // 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组
  4 // {3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
  5 
  6 #include <cstdio>
  7 #include <exception>
  8 
  9 int MinInOrder(int* numbers, int index1, int index2);
 10 
 11 int Min(int* numbers, int length)
 12 {
 13     if(numbers == nullptr || length <= 0)
 14         throw new std::exception("Invalid parameters");
 15  
 16     int index1 = 0;
 17     int index2 = length - 1;
 18     int indexMid = index1;
 19     while(numbers[index1] >= numbers[index2])
 20     {
 21         // 如果index1和index2指向相邻的两个数,
 22         // 则index1指向第一个递增子数组的最后一个数字,
 23         // index2指向第二个子数组的第一个数字,也就是数组中的最小数字
 24         if(index2 - index1 == 1)
 25         {
 26             indexMid = index2;
 27             break;
 28         }
 29  
 30         // 如果下标为index1、index2和indexMid指向的三个数字相等,
 31         // 则只能顺序查找
 32         indexMid = (index1 + index2) / 2;
 33         if(numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1])
 34             return MinInOrder(numbers, index1, index2);
 35 
 36         // 缩小查找范围
 37         if(numbers[indexMid] >= numbers[index1])
 38             index1 = indexMid;
 39         else if(numbers[indexMid] <= numbers[index2])
 40             index2 = indexMid;
 41     }
 42  
 43     return numbers[indexMid];
 44 }
 45 
 46 int MinInOrder(int* numbers, int index1, int index2)
 47 {
 48     int result = numbers[index1];
 49     for(int i = index1 + 1; i <= index2; ++i)
 50     {
 51         if(result > numbers[i])
 52             result = numbers[i];
 53     }
 54 
 55     return result;
 56 }
 57 
 58 // ====================测试代码====================
 59 void Test(int* numbers, int length, int expected)
 60 {
 61     int result = 0;
 62     try
 63     {
 64         result = Min(numbers, length);
 65 
 66         for(int i = 0; i < length; ++i)
 67             printf("%d ", numbers[i]);
 68 
 69         if(result == expected)
 70             printf("	passed
");
 71         else
 72             printf("	failed
");
 73     }
 74     catch (...)
 75     {
 76         if(numbers == nullptr)
 77             printf("Test passed.
");
 78         else
 79             printf("Test failed.
");
 80     }
 81 }
 82 
 83 int main(int argc, char* argv[])
 84 {
 85     // 典型输入,单调升序的数组的一个旋转
 86     int array1[] = { 3, 4, 5, 1, 2 };
 87     Test(array1, sizeof(array1) / sizeof(int), 1);
 88 
 89     // 有重复数字,并且重复的数字刚好的最小的数字
 90     int array2[] = { 3, 4, 5, 1, 1, 2 };
 91     Test(array2, sizeof(array2) / sizeof(int), 1);
 92 
 93     // 有重复数字,但重复的数字不是第一个数字和最后一个数字
 94     int array3[] = { 3, 4, 5, 1, 2, 2 };
 95     Test(array3, sizeof(array3) / sizeof(int), 1);
 96 
 97     // 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字
 98     int array4[] = { 1, 0, 1, 1, 1 };
 99     Test(array4, sizeof(array4) / sizeof(int), 0);
100 
101     // 单调升序数组,旋转0个元素,也就是单调升序数组本身
102     int array5[] = { 1, 2, 3, 4, 5 };
103     Test(array5, sizeof(array5) / sizeof(int), 1);
104 
105     // 数组中只有一个数字
106     int array6[] = { 2 };
107     Test(array6, sizeof(array6) / sizeof(int), 2);
108 
109     // 输入nullptr
110     Test(nullptr, 0, 0);
111 
112     return 0;
113 }
View Code

与官方答案相比较,我少考虑了很多种特殊情况,相差甚远。

原文地址:https://www.cnblogs.com/acm-jing/p/10391329.html