给定一个有序递增数组arr,其中不含有重复元素,请找到满足arr[i]==i条件的最左的位置。如果所有位置上的数都不满足条件,返回-1.
思路:
设置变量值res=-1,表示最后一次找到arr[i]==i的位置,初始值为-1表示没有找到
考虑以下情况,M代表中间位置:
1. arr[0]>N-1,由于整个数组是递增的,所以0~N-1范围内不可能出现arr[i]==i的情况
2. arr[N-1]<0,由于整个数组是递增的,所以0~N-1范围内也不可能出现arr[i]==i的情况
3. 当arr[M]>M时,由于位置的增量严格是1,数组值的增量最少为1,所以在M~N-1之间不可能出现arr[i]==i,只需要在0~M-1的范围上继续二分就可以
4. 当arr[M]<M时,同理,只需要在M+1~N-1的范围上继续二分
5. 当arr[M]=M时,更新res的值,res=M,但是由于我们找的是最左的位置,所以继续在0~M-1的范围上继续二分
public class LeftLocationOfArrayValueEqualsIndex {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr1={-2,0,1,3,5,6};
int[] arr2={1,2,3,4,5,6};
int[] arr3={-1,1,2,4,5,6};
int[] arr4={-1,0,1,2,3,5};
int[] arr5={-3,-1,0,5,6,9};
System.out.println(getIndex(arr1));
System.out.println(getIndex(arr2));
System.out.println(getIndex(arr3));
System.out.println(getIndex(arr4));
System.out.println(getIndex(arr5));
}
public static int getIndex(int[] arr) {
if(arr==null||arr.length==0)
return -1;
if(arr[0]>arr.length-1 || arr[arr.length-1]<0) //或 arr[0]>0 || arr[arr.length-1]<arr.length-1
return -1;
int left=0;
int right=arr.length-1;
int res=-1;
while(left<right){
int mid=left+(right-left)/2;
if(arr[mid]>mid)
right=mid-1;
else if(arr[mid]<mid)
left=mid+1;
else{
res=mid;
right=mid-1;
}
}
if(arr[left]==left)
res=left;
return res;
}
}