在数组A[0...n-1]中,有所谓的魔术索引,满足条件A[i]=i。给定一个有序整数数组,元素值各不相同,编写一个方法,在数组A中找到一个魔术索引,若存在的话。
进阶
如果数组元素有重复值,又该如何处理?
package cci;
public class CCI_9_3 {
//没有重复元素,采用二分查找的策略
public static int findMag(int[] A){
if(A==null)
return -1;
return findMag(A, 0, A.length-1);
}
private static int findMag(int[] A, int start, int end){
if(start<0 || end>A.length-1 || start>end)
return -1;
int mid = (start+end)/2;
if(A[mid]==mid)
return mid;
if(A[mid]<mid)
return findMag(A, mid+1, end);
else
return findMag(A, start, mid-1);
}
//存在重复元素的话,不能再采用二分查找的策略
//
public static int findMagDup(int[] A){
if(A==null)
return -1;
return findMagDup(A, 0, A.length-1);
}
private static int findMagDup(int[] A, int start, int end){
if(start<0 || end>A.length-1 || start>end)
return -1;
int mid = (start+end)/2;
int midVal = A[mid];
if(mid == midVal)
return mid;
//这里比较中间下标和中间值已经没有意义,所以直接折半查找
//在查找的时候,如果midVal<mid,那么可以舍弃下标midVal和mid之间的值,因为数组是有序的,这些
//位置的值一定比下标小
int left = findMagDup(A, start, Math.min(midVal, mid-1));
if(left != -1)
return left;
int right = findMagDup(A, Math.max(midVal, mid+1), end);
return right;
}
public static void main(String[] args) {
int[] A1 = {0,2,3,4,5,8};
int[] B1 = null;
int[] C1 = {-5,-3,-2,1,2,4,6};
int result = findMag(C1);
int[] A2 = {-1,0,2,2,2,3,4,6,7};
int resultDup = findMagDup(A2);
System.out.println(resultDup);
}
}