题目:
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.
题意:
给定一个数组,该数组是有序的,旋转数组的意思是将数组的前面一部分加到了数组的后面,比如1,2,3,4,5,旋转后的一个数组是4,5,1,2,3。但是与“Search in Rotated Sorted Array”题目不同的是现在的数组中允许有重复元素。
之前的思路是:我们将数组分为前面一部分与后面一部分,比如上面的数组,前面一部分是4,5;后面一部分是1,2,3。采用二分法查找时通过比较目标元素与数组的最后一个元素的关系可以判断出目标数字是在前面一部分中还是后面一部分中。二分查找时根据nums[middle]值也可以判断出nums[middle]是属于前面一部分还是属于后面一部分。从而再来调整二分的范围。
现在的思路:现在的问题是允许数组中元素值相同。比如1,3,1,1,nums[0]与nums[2]都是1,都与最后一个数字相同,所以此刻是无法判断这个1是属于前面一部分还是后面一部分。这种情况就属于最坏情况,此时需要通过O(n)的时间复杂度从前往后遍历去查找是否存在目标值。
具体代码如下:
class Solution {
public:
bool search(vector<int>& nums, int target) {
if (target == nums[0])return true;
else if (target == nums[nums.size() - 1])return true;
int start = 0;
int end = nums.size() - 1;
int middle = (start + end) / 2;
while (start <= end){
if (nums[middle] == target)return true;
else if (nums[end] > nums[start]){
if (nums[middle] > target)end = middle - 1;
else start = middle + 1;
}
else{
if (target > nums[end]){//target is in the before part
if (nums[middle] < nums[end])end = middle - 1;
else if (nums[middle] == nums[end]){//the worest case
for (int i = 0; i < nums.size(); i++){
if (nums[i] == target)return true;
}
return false;
}
else if (nums[middle] > target)end = middle - 1;
else start = middle + 1;
}
else{//target is in the last part
if (nums[middle] > nums[end])start = middle + 1;
else if (nums[middle] == nums[end]){//the worset case
for (int i = 0; i < nums.size(); i++){
if (nums[i] == target)return true;
}
return false;
}
else if (nums[middle] > target)end = middle - 1;
else start = middle + 1;
}
}
middle = (start + end) / 2;
}
return false;
}
};