剑指offer旋转数组的最小数字(二分)

Posted ITAK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer旋转数组的最小数字(二分)相关的知识,希望对你有一定的参考价值。

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组3,4,5,1,2为1,2,3,4,5的一个旋转,该数组的最小值为1。 NOTE:给出的所 有元素都大于0,若数组大小为0,请返回0。

解题思路

首先观察这个数组有什么特点,它是由有序数组旋转而来的,如果有旋转的话,那么就存在一个下标 i ( i > = 1 ) i(i>=1) i(i>=1)将有序数组分为两个有序数组,使得 [ 0 , i − 1 ] [0,i-1] [0,i1] [ i , n − 1 ] [i,n-1] [i,n1] (n:数组中数的个数) 这两个区间是有序的,那么我们就是要找到这个 i i i,然后输出 a i a_i ai 就是答案。那么怎么找呢,我们考虑二分,旋转之后的数组满足一个条件 a l ≥ a r a_l\\ge a_r alar,初始值 l = 0 , r = n − 1 l=0, r=n-1 l=0,r=n1,那么我们取中间值 m = l + r 2 m=\\frac l+r 2 m=2l+r
如果满足 a m ≥ a l 那 么 l = m ; a_m \\ge a_l那么 l=m; amall=m;
如果满足 a m ≤ a r 那 么 r = m ; a_m \\le a_r那么 r=m; amarr=m;
r − l = 1 r-l=1 rl=1 的时候,我们就找到答案了,输出 a r a_r ar

代码如下:

class Solution 
public:
    int minNumberInRotateArray(vector<int> a) 
        int l = 0, r = a.size()-1;
        while(a[l] >= a[r]) 
            if(r-l == 1) return a[r]; //结束条件,即找到所在下标i
            int m = (l+r)/2;
            if(a[m] >= a[l]) l=m;
            if(a[m] <= a[r]) r=m;
        
        return a[0];//如果没有旋转,即为有序数组
    
;

以上是关于剑指offer旋转数组的最小数字(二分)的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer旋转数组的最小数字(二分)

剑指 Offer 11. 旋转数组的最小数字-二分查找

剑指 Offer 11. 旋转数组的最小数字-二分查找

剑指 Offer 11. 旋转数组的最小数字 154. 寻找旋转排序数组中的最小值 II 二分

旋转数组的最小数字-剑指Offer

剑指offer-7.旋转数组的最小数字