Happyunlimited 2020-02-21
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{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,中间值和两边都相等,这时候找最小值需要顺序扫描法