您的位置:首页 > 其它

【34】旋转数组的最小数字

2014-06-14 23:29 169 查看
题目:把一个递增数组的前几个元素移动到数组的末尾,我们称之为数组的旋转。输入一个递增排序数组的旋转,输出旋转数组的最小元素。例如输入3 4 5 6 7 1 2,则最小元素为1。规定递增元素是没有重复元素的。

分析:
1. 最简单做法是从头到尾遍历数组,就可以求出最小元素。时间复杂度O(n),但是这个是最朴素的方法。

2. 根据旋转数组的性质,旋转数组满足“递增-最小值-递增”的性质。利用这个性质我们可以比较快速的求出最小元素。例如3 4 5 6 7 - 1 - 2,就是满足递增-最小值-递增
    具体的做法是设置两个指针p1和p2,初始化分别指向数组的头和尾,然后比较两个指针所指的值和两个指针中间位置的值的关系。mid = (p1+p2) >> 1;
   (1)如果arr[mid] > arr[p2],说明最小元素在mid之后则p1 = mid
   (2)如果arr[mid]  < arr[p2],说明最小元素在mid之前则p2 = mid
   (3)如果两个指针相差为1的时候,最小值即为最小元素
    时间复杂度为O(logn),因为每次可以跳到中间位置,类似二分搜索。
 
3. 举例旋转数组3 4 5 6 7 1 2
    第一次p1指向3,p2指向2,mid指向6,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid
    第二次p1指向6,p2指向2,mid指向7,发现arr[mid] > arr[p2]说明最小元素在mid之后,则p1 = mid
    第三次p1指向7,p2指向2,mid指向1,发现arr[mid] < arr[p2]说明最小元素在mid之前,则p2 = mid
    第四次p1指向7,p2指向1,此时p1和p2差1,则最小元素为1.

4. 代码

#include<iostream>
#include<algorithm>
using namespace std;

//求最小元素
int GetMinNum(int *arrNum, int n){
//不合法数据
if(arrNum == NULL || n <= 0){
return -1;
}
int left = 0;
int right = n-1;
while(left < right){
if(right == left+1){
return min(arrNum[left], arrNum[right]);
}
int mid = (left+right)>>1;
if(arrNum[mid] > arrNum[right]){
left = mid;
}
else{
right = mid;
}
}
}

int main(){
int arrNum[] = {3,4,5,6,7,1,2};
int value = GetMinNum(arrNum, 7);
cout<<value<<endl; //输出1
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: