public class Test { // 已知数组A是由有序数组B(数组B未知)向右移动n(0<=n<=B.length)位得到 // 例如 A = {4, 5, 1, 2, 3} 由 B = {1, 2, 3, 4, 5} 向右移动2位得到 // 求在数组A中搜索元素x private static int search(int[] a, int h, int t, int x) { if (h > t) return -1; int result = -1; int mid = (h + t) / 2; if (a[mid] == x) return mid; if (a[h] == a[t] && a[h] == a[mid]) { // 这种情况无法判断哪边是递增,那边是旋转数组,如下 // a = {5, X, 5, X, 5} // a = {5, 5, 5, 6, 5} // a = {5, 6, 5, 5, 5} result = search(a, h, mid - 1, x); if (result == -1) result = search(a, mid + 1, t, x); } else if (a[h] < a[t]) { result = binarySearch(a, h, t, x); } else { // a[h] > a[t] || ( a[h] == a[t] && a[h] != a[mid] ) if (a[mid] >= a[h]) { // a[h]~a[mid]为递增,a[mid+1]~a[t]为旋转数组 result = x >= a[h] ? binarySearch(a, h, mid - 1, x) : search(a, mid + 1, t, x); } else { // a[h]~a[mid]为旋转数组,a[mid+1]~a[t]为递增 result = x >= a[mid + 1] ? binarySearch(a, mid + 1, t, x) : search(a, h, mid - 1, x); } } return result; } // 第二种方法,先找出数组移位的位数,然后判断应该在哪一段进行二分查找 private static int getMoveStep(int[] a, int h, int t) { if (h >= t) return 0; int low = h; int high = t; int mid = (low + high) / 2; int step = 0; if (a[low] == a[high]) { // 这是一种无法判断哪边是递增序列的情况 step = getMoveStep(a, h, mid - 1); if (step == 0) step = getMoveStep(a, mid + 1, t); } else { while (a[low] > a[high]) { mid = (low + high) / 2; if (a[mid] >= a[low]) { // 递增序列在mid左边 step = low = mid + 1; } else { // 递增序列在mid右边 high = mid - 1; } } } return step; } // 利用y移位次数查找 private static int searchByMove(int[] a, int x) { int result; int step = getMoveStep(a, 0, a.length - 1); if (step != 0) { result = x > a[0] ? binarySearch(a, 0, step - 1, x) : binarySearch(a, step, a.length - 1, x); } else { result = binarySearch(a, 0, a.length - 1, x); } return result; } private static int binarySearch(int[] a, int h, int t, int x) { int low = h; int high = t; int mid; while (low <= high) { mid = (low + high) / 2; if (a[mid] == x) { return mid; } else if (a[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return -1; } public static void main(String[] args) { int[] a = {4, 5, 1, 2, 3}; int[] b = {5, 5, 5, 7, 5}; int[] c = {5, 3, 5, 5, 5}; int[] d = {5, 5, 3, 4, 5, 5, 5}; int[] e = {5, 5, 5, 5, 5}; int[] f = {1, 2, 3, 4, 5}; System.out.println(search(a, 0, a.length - 1, 1)); System.out.println(search(b, 0, b.length - 1, 7)); System.out.println(search(c, 0, c.length - 1, 3)); System.out.println(search(d, 0, d.length - 1, 3)); System.out.println(search(e, 0, e.length - 1, 3)); System.out.println(search(f, 0, f.length - 1, 2)); System.out.println(); System.out.println(searchByMove(a, 1)); System.out.println(searchByMove(b, 7)); System.out.println(searchByMove(c, 3)); System.out.println(searchByMove(d, 3)); System.out.println(searchByMove(e, 3)); System.out.println(searchByMove(f, 2)); } }