标签:判断 nbsp leetcode arch 比较大小 重要 while lap get
leeetcode 33. Search in Rotated Sorted Array
leetcode 81
leetcode 153. Find Minimum in Rotated Sorted Array
这几道的相似处是:都是部分有序的数组,可以用二分搜索来做。最重要的是判断到底是左区间还是右区间。
leetcode 33:
if(nums[mid] == target) return mid ; else if(nums[mid] < target) { //如果左半区间是升序的,一定不可能在左半区间,如果左半区间是非升序的(nums[l] > nums[mid]) , 且 //target >= nums[l],就一定在左半区间 if(nums[l] > nums[mid] && target >= nums[l]) r = mid- 1; else l = mid + 1 ; } else { //如果右半区间是升序的,就一定不在右半区间,如果右半区间是非升序的(nums[mid] > nums[r]),且 //target <= nums[r] , 就一定在右半区间 if(nums[mid] > nums[r] && target <= nums[r]) l = mid + 1 ; else r = mid - 1 ; }
leetcode 81: 81相较33复杂了很多,33题没有nums[mid] == nums[r] || nums[l] == nums[mid]这样的情况,所以通过比较大小就可以直接判断某区间到底是升序的还是降序。而81题中nums[l] == nums[mid] || nums[mid] == nums[r]的区间可能是升序的或是非升序的。
nums[mid] < target的情况下,以左区间为例 ,如果是有序的,左区间一定不可能,如果是非有序的且target >= nums[l],就一定是左区间。问题是如何判断左区间是不是非有序的,33题中通过nums[l] > nums[mid]就可以判断左区间一定是非有序的,但是nums[l] == nums[mid]的情况下左区间可能是非有序的,也可能是有序的。如果左区间是非有序的,nums[mid] == nums[r] , 如果左区间是有序的,nums[mid]也有可能==nums[r] , 所以当nums[l] == nums[mid] == nums[r]时,没法判断左区间是有序的还是非有序的,但是这时可以判断l , r 一定不可能,所以当nums[l] == nums[mid] == nums[r] , l++ , r-- ;
所以当nums[mid] != target && nums[l] == nums[mid] && nums[mid] == nums[r] l++ , r-- ;
当nums[mid] < target , 如果nums[l] == nums[mid] 左区间一定是有序的;原因在于如果左区间是非有序的,那么nums[mid] == nums[r] , 但是nums[mid] 又不可能==nums[r],所以左区间一定是有序区间。所以如果nums[l] > nums[mid],左区间一定是非有序区间。
if(nums[l] > nums[mid] && target >= nums[l]) r = mid - 1 ;
else l = mid + 1 ;
nums[mid] > target的时候镜像一下就对了;
class Solution { public: bool search(vector<int>& nums, int target) { if(nums.empty()) return false ; int l = 0 , r = nums.size() - 1 ; while(l <= r) { int mid = l + (r - l) / 2 ; if(nums[mid] == target) return true ; else if(nums[l] == nums[mid] && nums[mid] == nums[r]) { l++ ; r-- ; } else if(nums[mid] < target) { if(nums[l] > nums[mid] && target >= nums[l]) r = mid - 1 ; else l = mid + 1 ; } else { if(nums[mid] > nums[r] && target <= nums[r]) l = mid + 1 ; else r = mid - 1 ; } } return false ; } };
延伸一下问题:如果是求target的最小index呢?很简单,用res记录一下nums[mid] == target的所有mid中最小的那个就行了;
标签:判断 nbsp leetcode arch 比较大小 重要 while lap get
原文地址:https://www.cnblogs.com/mychen06/p/12630246.html