一 题目
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
Accepted 476,367 Submissions 1,436,616
二 分析
medium级别难度。给定一个 “升序” 的 无重复 数组,从中寻找target值。
这个数组不是真正意义的升序,是被rotated (旋转)过的升序。
因为要求时间复杂度在O(log n). 所以容易想到二分查找。
这里不能直接使用二分查找。需要寻找规律.对于普通升序数组[0,1,2,3,4,5,6,7],其旋转后可能情况有:
[1,2,3,4,5,6,7,0]
[2,3,4,5,6,7,0,1]
[3,4,5,6,7,0,1,2]
[4,5,6,7,0,1,2,3]
[5,6,7,0,1,2,3,4]
[6,7,0,1,2,3,4,5]
[7,0,1,2,3,4,5,6]
如红色标出所示,如果nums[mid]<nums[right],即中间的数小于最右边的数,那么mid(包括mid)右边的数是有序的,如果中间的数大于最右边的数,那么mid(包括mid)左边的数是有序的。那我们每次都可以折半查找。
这个很重要,也是解题的关键。我也是看了https://www.cnblogs.com/grandyang/p/4325648.html 才明白。
有序的特点已经找到了,我们只需要判断目标值是否在绝对升序的范围内,就可以确定二分的边界了。
注意一点:mid 取值 直接=(left+right)/2 .这样有的边界case两个数值的{1,3} 求1过不了。
代码如下:
public static void main(String[] args) {
int[] nums2 = {3,1};
int res2 = search(nums2,3);
System.out.println(res2);
int[] nums1 = {1,3};
int res1 = search(nums1,1);
System.out.println(res1);
res1 = search(nums1,3);
System.out.println(res1);
int[] nums = {4,5,6,7,0,1,2};
int res = search(nums,0);
System.out.println(res);
res = search(nums,3);
System.out.println(res);
}
//二分
public static int search(int[] nums, int target) {
//coner case
if(nums ==null){
return -1;
}
int left =0;
int right = nums.length-1;
while(left<=right){
int mid = left+((right - left) >> 1);
if(nums[mid] == target){
return mid;
}
//右边有序
if(nums[ mid] < nums[right ]){
//target落在右侧区间
if(nums[mid]<target&&target<= nums[right] ) {
left = mid+1;
}else{
//target落在左侧区间
right = mid -1;
}
}else{
//左边有序
// target落在左侧区间
if(nums[left] <=target && target< nums[mid] ){
right = mid -1;
}else{
//target落在右侧区间
left = mid +1;
}
}
}
return -1;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Search in Rotated Sorted Array.
Memory Usage: 37.1 MB, less than 81.76% of Java online submissions forSearch in Rotated Sorted Array.