81. Search in Rotated Sorted Array II
Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
分析
这个题目是33. Search in Rotated Sorted Array的衍生,只是增加了一个元素可能重复的条件。解题方法还是两种方法,一种是找到pivot后二分法查找;另一种是变异的二分法;解释见源码。
源码
方法1:查找pivot
class Solution {
public:
bool search(vector<int>& nums, int target) {
int pivot = indexOfPivot(nums);
if(pivot == -1) {
return binarySearch(nums,0,nums.size() - 1, target);
} else {
if(nums[pivot] <= target && target <= nums[nums.size() - 1]) {
return binarySearch(nums, pivot, nums.size() - 1, target);
} else {
return binarySearch(nums, 0, pivot - 1, target);
}
}
}
private:
// 寻找pivot
int indexOfPivot(vector<int>& nums) {
int ret = -1;
if(nums.size() < 2) return ret;
for(int i = 1; i < nums.size(); i++) {
if(nums[i-1] > nums[i]) {
ret = i;
break;
}
}
return ret;
}
// 二分法
bool binarySearch(vector<int>& nums, int first, int last, int target) {
bool ret = false;
int middle, low = first, high = last;
while(low <= high) {
middle = (low + high) / 2;
if(nums[middle] == target) {
ret = true;
break;
} else if(nums[middle] < target) {
low = middle + 1;
} else {
high = middle - 1;
}
}
return ret;
}
};
方法二:变异二分法
class Solution {
public:
bool search(vector<int>& nums, int target) {
bool ret = false;
int middle, low = 0, high = nums.size() - 1;
while(low <= high) {
middle = (low + high) / 2;
if(nums[middle] == target) { // 找到直接退出
ret = true;
break;
}
// 因为序列有重复元素,那么nums[i] <= nums[j]就不能保证i...j间是有序的
// 比如[1,5,3,1,1,1,1], 这时可以拆成三种情况来考虑
// nums[i] < nums[j] 保证i...j有序
// nums[i] > nums[j] 保证i...j间无序,那么剩下的一部分肯定有序
// nums[i] == nums[j] 那么让i和j元素重复,让i往前走一步
if(nums[low] < nums[middle]) { //
if(nums[low] <= target && target < nums[middle]) {
high = middle - 1;
} else {
low = middle + 1;
}
} else if(nums[low] > nums[middle]) {
if(nums[middle] < target && target <= nums[high]) {
low = middle + 1;
} else {
high = middle - 1;
}
} else {
low++;
}
}
return ret;
}
};