旋转数组的最小数字

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


算法思路:

1.旋转数组的特点就是一个数组为两个有序的数组,这里以升序为例
2.将数组的start和end获得,求mid,然后用numbers[mid]分别和numbers[start],numbers[end]比较
如果numbers[mid]>=numbers[start]:start=mid,循环比较mid之后的数组
如果numbers[mid]<=numbers[end]: end=mid,循环比较mid之前的数组
3.直到start和end相邻的时候,此时numbers[end]为最小的数字
注意:当numbers[mid],numbers[start],numbers[end]三个都相等的时候,应该采用顺序遍历的方式找到最小值


#include<iostream>
using namespace std;
int shunxu(int* numbers,int start,int end);
int Min(int *numbers,int length) throw (exception)
{
    if(numbers==NULL||length<=0)
        throw exception("参数错误!");
    int start=0,end=length-1;//start指向前面的有序数组的的下标,end指向后面有序数组的下标
    int mid=start;//将mid初始化为start,如果是数组没有旋转不进入while循环,直接return numbers[0]
    while(true)
    {
        if(start-end==-1)//start与end相差1时候则证明start为最大的数,end为最小的数
        {
            mid=end;
            break;
        }
        mid=(start+end)/2;
        //如果numbers[mid],numbers[start],numbers[end]相等的话,需要顺序遍历
        if(numbers[mid]==numbers[start]&&numbers[mid]==numbers[end])
        {
            return shunxu(numbers,start,end);
        }
        if(numbers[mid]>=numbers[start])//此时表示最小数在mid后面
            start=mid;
        else if(numbers[mid]<=numbers[end])//此时表示最小数在mid前面
            end=mid;
    }
    return numbers[mid];
}
//顺序遍历数组找最小值
int shunxu(int* numbers,int start,int end)
{
    int min=numbers[start];
    for(int i=start+1;i<=end;i++)
    {
        if(min>numbers[i])
            min=numbers[i];
    }
    return min;
}
int main()
{
    int a[20]={1,1,1,0,1};
    cout<<Min(a,5);
    return 0;
}

运行结果:

 
原文地址:https://www.cnblogs.com/runninglzw/p/4491201.html