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.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2]
, target = 0 Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2]
, target = 3 Output: -1
题目理解:
给定一个递增数组,这和数组会按照某一点旋转,并且我们事先不知道,然后让让我们从这个未知的数组中去寻找某一个数。算法复杂度要求是O(logn),很明显是让我们用二分查找的方法去遍历,但是由于旋转之后无法直接去使用二分查找方法,应为nums[mid]可能会同时小于nums[left]和nums[right],会造成判断混乱。旋转的数组有一个特点就是,无论从哪一个位置开始旋转总会有其中一半部分是顺序的,利用这个特点,我们可以怎加一个判断条件,寻找有序的一部分,利用有序的部分进行判断,代码如下,这样搜索的时间复杂度为O(logn)
class Solution {
public int search(int[] nums, int target) {
int start=0;
int end=nums.length-1;
while(start<=end){ //binary search
int mid=(start+end)/2;
if(nums[mid]==target)
return mid;
//left in sort
if(nums[mid]>=nums[start]){
if(target<nums[mid]&&target>=nums[start])
end=mid-1;
else
start=mid+1;
}
//right in sout
else{
if(target<=nums[end]&&target>nums[mid])
start=mid+1;
else
end=mid-1;
}
}
return -1;
}
}
ps:由于两个题目相隔时间比较远,我第一题是用java处理的,第二题是用c++来处理问题的。
81. Search in Rotated Sorted Array II
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,0,1,2,2,5,6]
might become [2,5,6,0,0,1,2]
)
You are given a target value to search. If found in the array return true
, otherwise return false
.
Example 1:
Input: nums = [2,5,6,0,0,1,2]
, target = 0 Output: true
Example 2:
Input: nums = [2,5,6,0,0,1,2]
, target = 3 Output: false
Follow up:
- This is a follow up problem to Search in Rotated Sorted Array, where
nums
may contain duplicates. - Would this affect the run-time complexity? How and why?
题目理解:
第二题在原有的条件下,又增加一种情况就是允许数组里面的数是重复的,这样的情况会使得上一题的解法出现漏洞,当我们判断 if(nums[mid]>=nums[start]) 会出现 nums[mid] = nums[start] = nums[end]情况,我们可以通过对start右移来消除这种情况的发生。平均时间复杂度O(logn),最坏的情况为O(n)
class Solution {
public:
bool search(vector<int>& nums, int target) {
int start = 0;
int end = nums.size()-1;
while(start<= end){
// binary search
int mid = (start+end) /2;
if(nums[mid] == target)
return true;
if(nums[mid] > nums[start]){
if(target <nums[mid]&& target>=nums[start])
end = mid - 1;
else
start = mid + 1;
}
else if(nums[start] == nums[mid])
start++;
else{
if(target >nums[mid]&& target<=nums[end])
start = mid + 1;
else
end = mid - 1;
}
}
return false;
}
};