153. Find Minimum in Rotated Sorted Array
二分题目,由于rotated存在,a[mid]<key不能判断在哪一边搜索。
可以根据a[low]与a[high]的关系,来判断哪一边有序,哪一边存在rotate,进而缩小搜索区间。
开区间写法:(由于搜索区间和解区间都是[low, high],直接 [low, high])
class Solution { public: int findMin(vector<int>& nums) { int low=0, high=nums.size()-1; //[low,high] while (low<high){ if (nums[low]<nums[high]) return nums[low]; int mid=(low+high)/2; if (nums[mid]>nums[high]){ //left side in order, min in the right part low = mid+1; }else{ //right side in order, min in the left part high = mid; } } return nums[low]; } };
上面的写法是用 a[mid] 与 a[high] 比较的,这样是比与 a[low] 比较要好的。如果和 a[low] 比较,需要注意的是 a[low]=a[mid] 可能发生,由于没有重复元素,这种情况只可能在 low==mid 时发生,即 low=mid=high-1 时。由于上面 a[low]<a[high] 就会return,说明这里 a[low]>a[high],应该返回 high 的值,因此归类归到 a[low]<a[mid] 一类中。
这道题的followup,如果有重复元素,a[low]==a[mid] 即有可能是 low==mid 这一边界情况,也有可能是重复元素导致的 a[low]==a[mid],需要分别处理,比较繁琐。
而与 a[high] 比较,a[mid]==a[high] 只可能是重复元素导致的。
class Solution { public: int findMin(vector<int>& nums) { int low=0, high=nums.size()-1; //[low,high] while (low<high){ if (nums[low]<nums[high]) return nums[low]; int mid=(low+high)/2; if (nums[low]<=nums[mid]){ //left side in order, min in the right part low = mid+1; }else{ //right side in order, min in the left part high = mid; } } return nums[low]; } };
154. Find Minimum in Rotated Sorted Array II
有duplicate以后,nums[mid]==nums[high] 的情况就会发生,我们无法判断最小值是左边还是右边。
由于二分实质是维护low,high只是用来缩小区间,我们可以 --high,这样并不会把最小的元素skip掉。
class Solution { public: int findMin(vector<int>& nums) { int low=0, high=nums.size()-1; //[low,high] while (low<high){ if (nums[low]<nums[high]) return nums[low]; int mid=(low+high)/2; if (nums[mid]>nums[high]){ //left side in order, min in the right part low = mid+1; }else if (nums[mid]<nums[high]){ //right side in order, min in the left part high = mid; }else{ // nums[mid]==nums[high] --high; } } return nums[low]; } };
类似题目:
Search in Rotated Sorted Array
reference:
原文地址:https://www.cnblogs.com/hankunyan/p/9926554.html