Search in Rotated Sorted Array 系列
33. Search in Rotated Sorted Array
介绍
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
Subscribe to see which companies asked this question.
解答
这道题目依旧可以利用二分法来进行数据的查找,在确定了中间结点之后,我们随后需要确定当中间结点是在前半部分的递增区间内还是后半部分的递增区间内。
因为题意中得知无重复元素,可以确定要么处于前半部分递增区间,要么处于后半部分递增区间,或者就是和端点元素重合。
然后再缩小查找范围。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left <= right)
{
int mid = (left+right)/2;
if(nums[mid] == target)
return mid;
if(nums[left] <= nums[mid]) //前半部分序列
{
if(target >= nums[left] && target < nums[mid])
right = mid-1;
else
left = mid+1;
}
else //后半部分序列
{
if(target > nums[mid] && target <= nums[right])
left = mid+1;
else
right = mid-1;
}
}
return -1;
}
};
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?
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
Write a function to determine if a given target is in the array.
The array may contain duplicates.
解答
此题目的关键点在于,循环数组中的元素可能重复。所以就会带来一定上的不同。
主要在于:
对于上题,如果中间点的值和端点的值相同,我们确定中间点和断点的值是重合的。
但是本题中,我们无法得到此种结果,所以,当中间点和端点元素重合的时候,我们是无法判断中间点位于哪一个递增区间的。此时只能选择遍历来查找对应结点。
class Solution {
public:
//平均时间复杂度为O(logn),最坏情况下O(n),时间复杂度有增加
bool search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left <= right)
{
int mid = left + (right - left)/2;
if(nums[mid] == target)
return true;
if(nums[left] < nums[mid]) //前半部分序列
{
if(target > nums[mid] || target < nums[left])
left = mid+1;
else
right = mid-1;
}else if(nums[left] > nums[mid]) //后半部分序列
{
if(target < nums[mid] || target > nums[right])
right = mid-1;
else
left = mid+1;
}else //无法判断,只能遍历
{
while(left <= right)
{
if(nums[left++] == target)
return true;
}
}
}
return false;
}
};