Description:
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
Analysis:
- Use Binary Search to find the index of the divider in the rotated array, like the following above show… (Binary Search definitely works here.)
- If the index of the divider is -1, it means the length of the array is 0, we just return -1.
- If the index of the divider is 0, it means the array is not rotated, then we use Binary Search to search the target in the whole array.
- If the index of the division is above 0, then we continue to compare
target
withnums[0]
.
- If
target < nums[0]
, the target may exist in the right part of the array. - Else, the target may exist in the left part of the array.
- Finally, we use Binary Search to search the target in the corresponding part.
Code:
class Solution {
public int search(int[] nums, int target) {
int pivot = findPivot(nums);
if(pivot == -1) {
return -1;
}else if(pivot == 0) {
return binarySearch(nums, 0, nums.length-1, target);
}else {
int res = binarySearch(nums, 0, pivot-1, target);
if(res != -1) {
return res;
}else {
return binarySearch(nums, pivot, nums.length-1, target);
}
}
}
public int findPivot(int[] nums) {
if(nums.length == 0) {
return -1;
}else if(nums[0] <= nums[nums.length-1]) {
return 0;
}else {
int left = 1, right = nums.length-1;
while(left <= right) {
int mid = left + (right-left) / 2;
if(nums[mid] < nums[mid-1]) {
return mid;
}else if(nums[mid] < nums[0]) {
right = mid - 1;
}else {
left = mid + 1;
}
}
return -1;
}
}
public int binarySearch(int[] nums, int left, int right, int target) {
while(left <= right) {
int mid = left + (right-left) / 2;
if(nums[mid] == target) {
return mid;
}else if(nums[mid] < target){
left = mid + 1;
}else {
right = mid - 1;
}
}
return -1;
}
}