【算法】——查找:旋转数组的最小数字(改造二分法)

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

分析:既然说是改造的二分法,那么就是找到中间值,然后根据左边还是右边去找最小值,然后在左边或者右边再找中间值再分左边和右边。

现在举例来人工肉眼找出最小值,然后找规律

因为是递增的旋转,所以最小值一定是在大值的右边

其中有一个关键的问题:如何判断到底是左边有序还是右边有序?

答:

if(arr[mid]>arr[begin])//那么就是左边有序,因为是递增数组的旋转数组
{
    //如果是左边有序的话就保留右边,那么begin就变成mid
    begin=mid;
}
//否则就是右边有序,end变成mid
else
{
    end=mid;
}

整个完整算法

int min(int *arr,int len)
{
    int begin=0;
    int end=len-1;
    //考虑数组本身还是递增数组的情况
    if(arr[begin]<arr[end])
    {
        return arr[begin];
     }
    //正常情况
    //循环的条件是当不是值有两个元素的时候回,因为只有两个元素的时候,根据规律直接返回右边那个元素为最小值
    while(begin+1<end)
    {
        int mid=begin+((end-begin)>>1);
        if(arr[begin]>=arr[mid])//根据规律在这个时候是右边有序 
        {
            end=mid;//保留无序的一边 
        }
        else
        {
            begin=mid;
        }
     }
     //当只有两个元素的时候,就返回右边那个元素
     return arr[end];  
}
//在上面情况除外,还有一种是重复的时候的坑,10111,中间值和两边都相等,这时候找最小值需要顺序扫描法

猜你喜欢

转载自www.cnblogs.com/jessie99/p/12342535.html