Suppose a sorted array 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.
方法一:先找出旋转数组的最小节点,再进行分段二分查找public class Solution {
public int findPivot(int [] a){//找出旋转数组的最小值下标
int l = 0;
int r = a.length-1;
int pivot = l;
while(l<r && a[l] >= a[r]){//注意条件
if(r - l == 1){
pivot = r;
break;
}
int mid = (l+r)/2;
if(a[mid] <= a[l]) r = mid;//和二分查找的变化有区别
else l = mid;
}
return pivot;
}
public int binaySearch(int [] a, int target, int l, int r){//真二分查找
while(l <= r){
int mid = (l+r)/2;
if(a[mid] < target) l = mid+1;
else if(a[mid] > target) r = mid-1;
else return mid;
}
return -1;
}
public int search(int[] A, int target) {
if(A.length == 0) return -1;
int pivot = findPivot(A);
//System.out.println(pivot);
int res1 = binaySearch(A, target, 0, pivot-1);
if(res1 != -1) return res1;
else return binaySearch(A, target, pivot, A.length-1);
}
}
方法二:递归查找
public int search(int[] A, int target) {
return find(A, 0, A.length - 1, target);
}
private int find(int[] arr, int p, int q, int x) {
if (p > q)
return -1;
int mid = (p + q) / 2;
if (arr[mid] == x)
return mid;
if (arr[p] < arr[mid]) { // left is ordered, right is broken
if (arr[p] <= x && x <= arr[mid]) // x is in the left ordered part
return find(arr, p, mid - 1, x);
else // x doesn't belong to left ordered part
return find(arr, mid + 1, q, x);
} else if (arr[p] > arr[mid]) {// left is broken, so right is ordered
if (arr[mid] <= x && x <= arr[q])
return find(arr, mid + 1, q, x);
else
return find(arr, p, mid - 1, x);
} else { // a[p] == a[mid], directly search right
return find(arr, mid + 1, q, x);
}
}