题目:把一个数组的最开始若干个元素搬移到数组最后,我们称之为数组的旋转,现输入一个递增的旋转过的数组,例如我们输入{3,4,5,1,2},其实是由数组{1,2,3,4,5}旋转而来,现需要找到最小元素;
方法描述:(1)顺序查找,遍历一次数组即可,但是时间复杂度O(N)
(2)原来数组是有序的,有序数组我们查找一个数组元素使用二分查找,时间复杂度为O(logN),又因为旋转以后的数组其实是由两个有序的数组组成,所以我们可以利用二分查找思想解决这道题;
代码:
1 //旋转有序数组查找最小元素
2 #include<stdio.h>
3 #include<assert.h>
4 //顺序查找
5 int MininOrder(int *arr,int len)
6 {
7 int min = arr[0];
8 int i = 1;
9 for(;i<len;i++)
10 {
11 if(min>arr[i])
12 min = arr[i];
13 }
14 return min;
15 }
16 int fun(int *arr,int len)
17 {
18 assert(arr && len>0);
19 int left = 0;
20 int right = len-1;
21 //数组本来就有序
22 if(arr[left]<arr[right])
23 return arr[left];
24 int index = 0;
25 while((right-left) != 1)
26 {
27 index = left + ((right-left)>>1);
28
29 //如果是{1,1,1,0,1}这种情况找不到,只能顺序查找
30 if(arr[index] == arr[left] && arr[left] == arr[right])
31 {
32 return MininOrder(arr,len);
33 }
34 if(arr[index]<=arr[right])
35 right = index;
36 else if(arr[index]>= arr[left])
37 left = index;
38 }
39 return arr[right];
40 }
41 int main()
42 {
43 int arr1[] = {3,4,5,1,2};
44 int arr2[] = {1,2,3,4,5,6};
45 int arr3[] = {3,4,5,6,1,2};
46 int len = sizeof(arr1)/sizeof(arr1[0]);
47 int arr4[] = {0,1,1,1,1,1};
48 int arr5[] = {1,0,1,1,1};
49 int arr6[] = {1,1,1,0,1};
50 printf("res1 = %d\n",fun(arr1,len));
51 printf("res2 = %d\n",fun(arr2,sizeof(arr2)/sizeof(int)));
52 printf("res3 = %d\n",fun(arr3,sizeof(arr3)/sizeof(int)));
53
54 printf("res4 = %d\n",fun(arr4,sizeof(arr4)/sizeof(int)));
55 printf("res5 = %d\n",fun(arr5,sizeof(arr5)/sizeof(int)));
56 printf("res6 = %d\n",fun(arr6,sizeof(arr6)/sizeof(int)));
57 return 0;
58 }