劍指offer-06:旋轉陣列的最小數字
阿新 • • 發佈:2018-12-05
問題
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。
思路
旋轉之後的陣列實際上可以劃分成兩個有序的子陣列:前面子陣列的大小都大於後面子陣列中的元素
注意到實際上最小的元素就是兩個子陣列的分界線。本題目給出的陣列一定程度上是排序的,因此我們試著用二分查詢法尋找這個最小的元素。
思路:
(1)我們用兩個指標left,right分別指向陣列的第一個元素和最後一個元素。按照題目的旋轉的規則,第一個元素應該是大於最後一個元素的(若沒有重複的元素時)。
(2)找到陣列的中間元素。
若中間元素大於第一個元素,此時最小元素位於中間元素的後面。我們可以讓left指向中間元素。
若中間元素小於第一個元素,此時最小元素位於中間元素的前面。我們可以讓right指向中間元素。
(3)按照以上思路,第一個指標left總是指向前面遞增陣列的元素,第二個指標right總是指向後面遞增的陣列元素。
程式碼實現
public class Solution06 {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length==0)
return 0;
int low = 0;
int high = array.length-1;
int mid = low;
while(array[low]>=array[high]){
if(array[low] == array[high]){
for(int i=low;i<array.length;i++){
if(array[low]!=array[i]){
low = i-1;
break;
}
}
for(int i=high;i>=0;i--){
if(array[high] !=array[i]){
high = i+1;
break;
}
}
}
if(high-low<=1){
mid = high;
break;
}
mid = (low+high)/2;
if(array[mid]>=array[low]){
low = mid;
}else if(array[mid]<=array[high]){
high = mid;
}
}
return array[mid];
}
public static void main(String[] args) {
int [] array={6,6,6,8,11,15,16,16,2,3,4,5,6,6,6};
Solution06 solu=new Solution06();
System.out.printf("%d",solu.minNumberInRotateArray(array));
}
}