leetcode剑指offer11 旋转数组的最小数字 简单

 

 

① O(n) 遍历,很简单。

② 二分,最坏情况下退化为 O(n).

如果 nums[l] < nums[r],那么当前序列肯定就是递增的,l 即最小位置。否则,进行二分:

如果 nums[mid] > nums[l],那么 mid 处肯定不会为最小值,即 l = mid + 1.

如果 nums[mid] < nums[r],那么 mid 可能为最小值,所以 r = mid.

而对于 nums[mid] == nums[l] 或者 nums[mid] == nums[r] 的情况,就只能排出当前 l 或者 r 位置,即 ++l,或者 --r

class Solution {
public:
    int minArray(const vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while(l < r && nums[l] >= nums[r]) {
            int mid = (l + r) >> 1;
            if(nums[mid] > nums[l]) l = mid + 1;
            else if(nums[mid] < nums[r]) r = mid;
            else if(nums[mid] == nums[l]) ++ l;
            else -- r;
        }
        return nums[l];
    }
};

 

还有另一种写法:二分判断时,只以 nums[r] 作为对比条件

如果 nums[mid] > nums[r],那么 mid 处肯定不为最小值,即 l = mid + 1

如果 nums[mid] < nums[r],那么 mid 可能为最小值,即 r = mid

否则就是 nums[mid] == nums[r],只能排出 r 位置,即 --r

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 @ 2021-09-14 23:34  rookie_Acmer  阅读(27)  评论(0)    收藏  举报