循环有序数组中查找指定元素
这道题目是我在快看漫画面试时的一道算法题:http://www.cnblogs.com/optor/p/8570548.html
当时现场并未写出解答来,现在有些后悔,其实就是在二分查找的基础上多加一些判断逻辑就可以解决了的啊!
现在我参考了别人的博客,已经写出了解法实现,不知道我的解法是不是最正规的,不过基本测试是通过了:
/**
* Created by clearbug on 2018/2/26.
*/
public class Solution {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 5));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 4));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 3));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 2));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 1));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 15));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 10));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 8));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 6));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 16));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 7));
System.out.println(s.search(new int[]{6, 8, 10, 15, 1, 2, 3, 4, 5}, 9));
}
public int search(int[] arr, int target) {
return searchHelper(arr, 0, arr.length - 1, target);
}
private int searchHelper(int[] arr, int start, int end, int target) {
if (start > end) {
return -1;
}
int middle = (start + end) / 2;
if (arr[middle] == target) {
return middle;
}
if (arr[middle] < arr[middle - 1] && arr[middle] < arr[middle + 1]) { // middle 即是分割点
if (target <= arr[end]) {
start = middle + 1;
} else {
end = middle - 1;
}
while (start <= end) {
middle = (start + end) / 2;
if (arr[middle] == target) {
return middle;
} else if (arr[middle] > target) {
end = middle - 1;
} else {
start = middle + 1;
}
}
} else if (arr[middle] > arr[end]) { // middle 在分割点左侧
if (target > arr[middle]) {
start = middle + 1;
return searchHelper(arr, start, end, target);
} else {
int leftRes = searchHelper(arr, start, middle - 1, target);
if (leftRes > -1) {
return leftRes;
}
int rightRes = searchHelper(arr, middle + 1, start, target);
if (rightRes > -1) {
return rightRes;
}
}
} else { // arr[middle] < arr[end], middle 在分割点右侧
if (target > arr[middle]) {
int leftRes = searchHelper(arr, start, middle - 1, target);
if (leftRes > -1) {
return leftRes;
}
int rightRes = searchHelper(arr, middle + 1, start, target);
if (rightRes > -1) {
return rightRes;
}
} else {
end = middle - 1;
return searchHelper(arr, start, end, target);
}
}
return -1;
}
}