1. 程式人生 > >【劍指Offer】面試題53 題目3

【劍指Offer】面試題53 題目3

題目3:升序陣列中,尋找數值和下標相等的元素

   [-3,-1,1,3,5]中的滿足條件的元素為3

   1. 挖掘特性

(1)如果某個位置(i)的值(m)小於該位置,即m<i,那麼這個位置之前的位置上的值肯定要比其相應的位置更小。原因是位置i是以1為步長,而整數的值之間又是升序關係,也就是至少也是以1為步長的,因此會呈現這樣的特性,證明如下:

                                     array[i-1]<=array[i]-1<i-1

(2)如果某個位置(i)的值(m)大於該位置,即m>i,那麼這個位置之後的位置上的值肯定要比其相應的位置更大。原因是位置i是以1為步長,而整數的值之間又是升序關係,也就是至少也是以1為步長的,因此會呈現這樣的特性,證明如下:

                                     array[i+1]>=array[i]+1>i+1

(3)升序,即對應著排序的陣列,可以考慮使用二分法查詢上面所說的“某個值”。

綜上,思路如下:

2. 思路

(1)首先使用二分法查找出middle處的值,如果該值和middle相等,那我們很幸運,找到了要找的值

(2)如果middle處的值和middle不相等,進而如果是array[middle]<middle,那麼middle左側的所有值都小於對應的索引,因此可以忽略middle及其左側的所有值,此時應該將left設定為left=middle+1

(3)如果array[middle]>middle, 那麼middle右側的所有值都大於對應的索引,因此可以忽略middle及其右側的所有值,此時應該將right設定為right=middle-1

3. 程式碼

package now.code53;
public class N53_timu3 {
public int GetNumberSameAsIndex(int[] numbers,int length) {
if(length==0) return -1;
int left=0;
int right=length-1;
while(left<=right) {
int middle=(left+right)/2;
if(numbers[middle]==middle) 
return middle;
if(numbers[middle]>middle) 
right=middle-1;
if(numbers[middle]<middle) 
left=middle+1;
}
return -1;
}
public static void main(String[] args) {
N53_timu3 n=new N53_timu3();
int[] numbers= {-5,-3,-1,3,6,8,10};
System.out.println(n.GetNumberSameAsIndex(numbers, numbers.length));
}
}