这道题让在旋转数组中找目标值,所以思路应该是在排好序的序列中进行二分查找
先给出代码,再逐块解析
public int search(int[] A, int target) {
if (A == null || A.length == 0) {
return -1;
}
int left = 0;
int right = A.length - 1;
while (left <= right) {
int middle = (left + right) / 2;
if (A[middle] == target)
return middle;
if (A[left] < A[middle]) {
if (target >= A[left] && A[middle] >= target)
right = middle - 1;
else
left = middle + 1;
} else if (A[left] > A[middle]) {
if (target >= A[middle] && A[right] >= target)
left = middle + 1;
else
right = middle - 1;
} else
left++;
}
return -1;
}
前面和二分查找思路一样,如果找到,返回middle
如果没找到就要分三种情况了,一种情况是left~middle是排好序的,一种情况是left~middle没排好序(如果不出现重复,middle~right一定是排好序的),还有一种是left和middle指针重合(详见边界问题分析)
如果是第一种情况,判断目标值是否在排好序的序列范围内,如果是,跳进这个序列,否则,跳到另一个序列去。
if (A[left] < A[middle]) {
if (target >= A[left] && target <= A[middle])
right = middle - 1;
else
left = middle + 1;
}
如果是第二种情况,判断目标值是否在排好序的序列范围内,如果是,跳进这个序列,否则,跳到另一个序列去。
else if (A[left] > A[middle]) {
if (target >= A[middle] && target <= A[right])
left = middle + 1;
else
right = middle - 1;
}
如果是第三种情况,直接left++就可以了。
边界情况分析
【9,1】
如果left指针和middle指针重合且target不在left和middle中。left=middle+1
如果left指针和right指针重合,此时不应该跳出循环,因为middle=left=right=(left+right)/2
直接返回A[middle],因为这个时候已经找到目标值。