本系列導(dǎo)航:劍指offer(第二版)java實現(xiàn)導(dǎo)航帖
面試題11:旋轉(zhuǎn)數(shù)組的最小數(shù)字
題目要求:
把一個數(shù)組最開始的若干個元素搬到末尾成為數(shù)組的旋轉(zhuǎn),如1,2,3,4,5=>3,4,5,1,2;0,1,1,1,1=>1,1,1,0,1;0,1,1,1,1=>1,0,1,1,1。求一個原本遞增的數(shù)組旋轉(zhuǎn)后的最小數(shù)字。
解題思路:
考察二分查找。原本有序,進行了旋轉(zhuǎn),但在一定程度上還是有序的。有了這個出發(fā)點,如果熟悉二分查找應(yīng)該就離最終結(jié)果差不多了。通過觀察中間點與左右點的關(guān)系,縮小范圍,從而找到最小值??s小范圍時要注意值相等的情況,尤其是左右中三個值都相等的情況,這種特殊情況是無法折半縮小范圍的,只能逐步縮小,即左右點各縮進一個單位。
此題比較考驗邏輯,明白為什么能用二分查找 && 把各個ifelse情況理清楚 -> 解決
package chapter2;
/**
* Created by ryder on 2017/6/28.
* 旋轉(zhuǎn)數(shù)組的最小數(shù)字
*/
public class P82_MinNumberInRotatedArray {
public static int min(int[] data){
if(data==null || data.length==0)
return -1;
int left = 0;
int right = data.length-1;
int mid;
while(left<right){
mid = left+(right-left)/2;
//left < right
if(data[left]<data[right])
return data[left];
//left > right
else if(data[left]>data[right]){
if(data[mid]>=data[left])
left = mid + 1;
else
right = mid;
}
//left = right
else{
if(data[left]<data[mid])
left = mid + 1;
else if(data[left]>data[mid])
right = mid;
else{
left = left+1;
right = right-1;
}
}
}
return data[right];
}
public static void main(String[] args){
int[] data1 = {3,4,5,1,2};
int[] data2 = {1,0,1,1,1};
int[] data3 = {1,1,1,0,1};
System.out.println(min(data1));
System.out.println(min(data2));
System.out.println(min(data3));
}
}
運行結(jié)果
1
0
0