题目: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
题意解析:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
解题思路一:
依次遍历遇到目标元素就返回索引,否则返回-1,代码如下:
public int search(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
if (target == nums[i]){
return i;
}
}
return -1;
}
此算法时间复杂度为O(n),但是不符合题意的时间复杂度。
提交代码之后:
Runtime: 0 ms, faster than 100.00% of Java online submissions for Search in Rotated Sorted Array.
Memory Usage: 38.8 MB, less than 26.61% of Java online submissions for Search in Rotated Sorted Array.
解题思路二:
通过题意给出的时间复杂度,以及在一个排序数组中搜索一个目标元素,我们很自然的想到了二分查找,但是由于数组可能会被翻转了一部分,所以在进行二分查找的时候,我们需要找到他的真实的二分位置,首先我们需要查找到数组在哪个位置进行的翻转,然后在进行二分查找的时候,其真实的二分位置,就是我们二分的位置+翻转的位置%数组的元素个数即可。
public int search(int[] nums, int target) {
int n = nums.length;
int lo=0,hi=n-1;
while(lo<hi){
int mid=(lo+hi)/2;
if(nums[mid]>nums[hi]) lo=mid+1;
else hi=mid;
}
int rot=lo;
lo=0;hi=n-1;
while(lo<=hi){
int mid=(lo+hi)/2;
int realmid=(mid+rot)%n;
if(nums[realmid]==target)return realmid;
if(nums[realmid]<target)lo=mid+1;
else hi=mid-1;
}
return -1;
}
此算法时间复杂度符合题意,提交代码之后:
Runtime: 0 ms, faster than 100.00% of Java online submissions for Search in Rotated Sorted Array.
Memory Usage: 36 MB, less than 100.00% of Java online submissions for Search in Rotated Sorted Array.