眼熟的噩梦二分法,一开始觉得思路太复杂于是先找到了前面的Ⅰleetcode日记(23)搜索旋转排序数组尝试写
这是新写的Ⅰ,之前的做法感觉太复杂了于是直接重写了一遍:
class Solution {
public:
int search(vector<int>& nums, int target) {
int up=nums.size()-1;
int down=0;
if(up==down) return nums[0]==target?0:-1;
while(up>=down){
int mid=(up+down)/2;
if(nums[mid]==target) return mid;
if(nums[down]<=nums[mid]&&nums[up]<=nums[mid]){
if(nums[mid]>=target&&nums[down]<=target) up=mid-1;
else down=mid+1;
}
else if(nums[down]>=nums[mid]&&nums[up]>=nums[mid]){
if(nums[mid]<=target&&nums[up]>=target) down=mid+1;
else up=mid-1;
}
else if(nums[down]<=nums[mid]&&nums[up]>=nums[mid]){
if(nums[mid]>=target) up=mid-1;
else down=mid+1;
}
}
return -1;
}
};
思路就是列出几种情况(旋转点在mid的左/右边、目标区域内的数组是正序排序),分别写出对于几种情况的对策,直到区间不存在说明其中没有包含target即可。
Ⅱ的方法和这个基本一致,只是Ⅱ多了一种特殊情况及up/down/mid三者值相等,此时无法判断它是上述哪一种情况,会陷入死循环,添加遇到这种情况up--即可。
class Solution {
public:
bool search(vector<int>& nums, int target) {
int up=nums.size()-1;
int down=0;
if(up==down) return nums[0]==target?1:0;
while(up>=down){
int mid=(up+down)/2;
if(nums[mid]==target) return 1;
if(nums[mid]==nums[down]&&nums[mid]==nums[up]) up--;
else if(nums[down]<=nums[mid]&&nums[up]<=nums[mid]){
if(nums[mid]>=target&&nums[down]<=target) up=mid-1;
else down=mid+1;
}
else if(nums[down]>=nums[mid]&&nums[up]>=nums[mid]){
if(nums[mid]<=target&&nums[up]>=target) down=mid+1;
else up=mid-1;
}
else if(nums[down]<=nums[mid]&&nums[up]>=nums[mid]){
if(nums[mid]>=target) up=mid-1;
else down=mid+1;
}
}
return 0;
}
};