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]; } };

浙公网安备 33010602011771号