旋转数组中的最小数字

问题:旋转数组中的最小数字剑指 Offer 11. 旋转数组的最小数字 - 力扣(LeetCode)

二分法:数组旋转点之前的非递减序列  >=   旋转点之后的非递减序列;

m是二分的中点,向下取整;比较numbers[m] 和 numbers[j]的大小;

大于则旋转点在[m+1,j];小于则旋转点在[i,m];相等则 采取 - -j 缩小区间范围(或者直接遍历数组);

难点理解:相等时,旋转点可能在左边也可能 在右边;为缩小区间范围,将j 减小,有两种情况:

一种是x < j,则 - -j ,[i,j]仍包含旋转点,缩小范围是安全的;

另一种是 x = j,则 - -j 丢失旋转点,这时有且只有 [i,x]之间的元素相等,且[m,j]之间的元素也相等,[i,j]区间即为左排序数组,二分下去一定是相等的数,也是本轮的numbers[i] .

 nums[x]=nums[j]=nums[m]number[i] ; i <= m < j =x ; 得出 m < x,那么numbers[m] >= numbers[i] 

 时间复杂度:O(log N) ; 空间复杂度:O(1)

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int i= 0,j = numbers.size()-1;
        while(i < j){
            int m = (i+j)/2;
            if(numbers[m]>numbers[j]) i = m+1;
            else if(numbers[m] < numbers[j]) j = m;
            else --j;
        }
        return numbers[i];
    }
};

 

posted @ 2023-02-14 15:44  QianFa01  阅读(26)  评论(0)    收藏  举报