CCI 9.3 魔术索引

在数组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);
	}

}


你可能感兴趣的:(二分查找)