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,中间值和两边都相等,这时候找最小值需要顺序扫描法