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.
此题和之前的题目Find Minimum in Rotated Sorted Array1,2的差别是,之前的题目是要求找出最小数组元素,而这道题要求我们找到target值相同的数组。具体说两个解题思路:
1.在原来Find Minimum in Rotated Sorted Array的解题思路上,加上target的取值范围,代码如下:
1 public class Solution { 2 public int search(int[] nums, int target) { 3 if(nums==null||nums.length==0) return -1; 4 int left = 0; 5 int right = nums.length-1; 6 while(left<right){ 7 int mid = left + (right-left)/2; 8 if(nums[mid]==target) return mid; 9 if(nums[mid]<nums[right]){ 10 if(target>nums[mid]&&target<=nums[right]) left = mid+1; 11 else right = mid-1; 12 }else{ 13 if(target>=nums[left]&&target<nums[mid]) right = mid-1; 14 else left = mid +1; 15 } 16 } 17 if(nums[left]==target) return left; 18 else return -1; 19 } 20 }
这里面有一些小细节,例如if(target>=nums[left]&&target<nums[mid])里面,为什么不能让nums[mid]和target相等,原因是要排除掉left=mid的情况;
下面是以right为比较对象的代码:
public class Solution {
public int search(int[] nums, int target) {
if(nums==null||nums.length==0) return -1;
int left = 0;
int right = nums.length-1;
while(left<right){
int mid = left+(right-left)/2;
if(nums[mid]==target) return mid;
if(nums[mid]<nums[right]){
if(target>nums[mid]&&target<=nums[right]){
left = mid+1;
}else{
right = mid-1;
}
}else if(nums[mid]>nums[right]){
if(target>=nums[left]&&target<nums[mid]){
right = mid-1;
}else{
left = mid+1;
}
}
}
return nums[left]==target?left:-1;
}
}
看了discussion的讲解,有另外一种方法如下:
首先,根据Find Minimum in Rotated Sorted Array的解题思路,可以先求出最小元素,然后,找出数组中的中间元素,他们的和与数组长度取余就是这些数组里面(按照数值大小排序)中间大小的数,代码如下:
public class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
while(left<right){
int mid = left+(right-left)/2;
if(nums[mid]<nums[right]){
right = mid;
}else{
left = mid+1;
}
}
int point = left;
left= 0;
right = nums.length-1;
while(left<=right){
int mid = left+(right-left)/2;
int realmid = (mid+point)%nums.length;
if(nums[realmid]==target) return realmid;
else if(nums[realmid]>target) right = mid-1;
else left = mid+1;
}
return -1;
}
}
需要注意的是
else if(nums[realmid]>target) right = mid-1;
else left = mid+1;
开始我思考为什么right = mid不可以,后来发现如果数组为【1】的话就不行了。