题目描述
给出一个转动过的有序数组,你事先不知道该数组转动了多少
(例如,0 1 2 4 5 6 7可能变为4 5 6 7 0 1 2).
在数组中搜索给出的目标值,如果能在数组中找到,返回它的索引,否则返回-1。
假设数组中不存在重复项。
思路:
首先判断排序数组是否翻转,如果没有翻转,直接使用二分查找,如果翻转,先使用变种的二分查找找到翻转位置,再分别在前半段与后半段进行二分查找寻找目标值。
public class HalfSearch {
public static void main(String[] args) {
//int[] a = {1,3,5,7,9,11};
int[] a = {3,5,7,9,11,1};
//int [] a ={9,11 ,1 ,3, 5 ,7};
HalfSearch halfSearch = new HalfSearch();
int index = halfSearch.search(a, 67);
System.out.println(index);
}
/**
*
* @param A int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] A, int target) {
// 如果没有反转,直接使用二分查找
if(A[0] < A[A.length-1]){
return binarySearch(A, 0, A.length-1, target);
}
// {1,3,5,7,9,11}; 9,11 1 3 5 7 {9,11 ,1 ,3, 5 ,7}
// 如果翻转,先使用变种的二分查找找到翻转位置,再分别在前半段与后半段进行二分查找寻找目标值。
// 找到旋转点
int start = 0;
int end = A.length-1;
// while(start <= end){
// int middle = (start + end) >> 1;
// if(A[middle] > A[end]){
// start = middle + 1; // 旋转点在右边
// }else if(A[middle] < A[end]){
// end = middle - 1; // 旋转点在左边
// }else{break;}
// }
while(start < end){
int middle = (start + end) >> 1;
if(A[middle] > A[end]){
start = middle + 1; // 旋转点在右边
}else {
end = middle ; // 旋转点在左边
}
}
int ret = binarySearch(A, 0, start-1, target);
if(-1 == ret){
ret = binarySearch(A, start, A.length-1, target);
}
return ret;
}
// 二分法
public int binarySearch(int[] A, int begin, int end, int target){
while(begin<=end){
int middle = (end+begin) >> 1;
if(A[middle] < target){
begin = middle+1;
}else if(A[middle] > target){
end = middle-1;
}else{
return middle;
}
}
return -1;
}
}