标签:
1
分析:
旋转数组之后的数组其实可以划分为两部分,前面的字数组都大于或者等于后面的字数组。最小的数字正好是两个子数组的分界线。我们可以用二分查找实现时间复杂度为O(logn)的查找。我们用两个指针,分别放在数组首尾,第一个元素应该大于等于最后一个元素(不一定,还有特殊情况)。如果中间元素大于等于第一个元素,则表明最小数在后半部分,如果中间元素小于等于最后一个元素,则表明最小数字在前半部分。
以下有两种特别的情况需要注意:
1.如果排序数组前面有0个元素搬到后面。
2.如果排序数组有相同的元素。例如:排序数组是{0,1,1,1,1},旋转数组可以是{1,0,1,1,1}也可以是{1,1,1,0,1},则无法直接判断最小数字到底在哪一部分。
实现代码:
#include<cstdio> #include<cstring> #include<cstdlib> int a[1000001]; int MidInorder(int k[],int l,int r) { int res = k[l]; for(int i = l+1; i <= r; i++) { if(res > k[i]) res = k[i]; } return res; } int SearchMin(int k[],int l,int r) { int mid = l; while(k[l] >= k[r]) { if(r - l == 1) { mid = r; break; } mid = l + (r-l)/2; if(k[l] == k[r] && k[l] == k[mid]) { return MidInorder(k,l,r); } if(k[mid] >= k[l]) l = mid; else if(k[mid] < k[r]) r = mid; } return k[mid]; } int main() { // freopen("D:\\1.txt","r",stdin); int n; while(scanf("%d",&n) != EOF) { for(int i = 0; i < n; i++) { scanf("%d",&a[i]); } int min = SearchMin(a,0,n-1); printf("%d\n",min); } return 0; }
标签:
原文地址:http://blog.csdn.net/biluyang/article/details/44018379