劍指Offer(第二版)面試題11:旋轉陣列的最小數字
阿新 • • 發佈:2019-02-20
劍指Offer面試題11:旋轉陣列的最小數字
題目一:把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。
輸入一個遞增排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。例如,陣列{3,4,5,1,2}是陣列{1,2,3,4,5}的一個旋轉,該陣列的最小值為1
思路1:暴力遍歷法:
/** * 方法1:暴力遍歷陣列,時間複雜度為O(n),指定不行,沒有利用到陣列有序的特性 * @param arr * @return */ public int getMin(int[] arr){ int min = arr[0]; for (int i = 1; i < arr.length; i++) { if(min>arr[i]) min = arr[i]; } return min; }
思路2:利用旋轉陣列部分有序的特點,進行二分查詢,減小時間複雜度。注意特殊情況的處理。
在上面的演算法中,當前面的若干個元素是指0個元素旋轉到後邊時,mid=0,則不會進入while迴圈,直接返回arr[0],即是陣列中的最小值。/** * 利用二分查詢的思想,時間複雜度為O(logn)。 * 注意對特殊情況的處理 * @param arr * @return */ public int getMin2(int[] arr){ int index1 = 0; int index2 = arr.length-1; int mid = 0; while(arr[index1]>=arr[index2]){ if(index2-index1==1){ // 兩個指標已經相鄰 mid = index2; break; } mid = (index1+index2)/2; // 如果下標為index1和index2以及mid指向的三個數字都相等,則只能順序查詢 if(arr[index1]==arr[index2]&&arr[mid]==arr[index1]){ return inInOrder(arr,index1,index2); } if(arr[mid]>=arr[index1]){ index1 = mid; }else if(arr[mid]<=arr[index2]){ index2 = mid; } } return arr[mid]; } public static int inInOrder(int[] arr, int index1, int index2) { int min = arr[index1]; for(int i = index1+1;i<=index2;i++){ if(min>arr[i]) min = arr[i]; } return min; }
反之進行二分查詢,根據條件變化左右指標,直到兩個指標相鄰。
特殊情況:前、後以及mid指標所指向的數均相同,則不能判斷該如何移動前後指標,此時,必須在前後指標範圍內使用順序查詢來搞定。
如果對你有幫助,記得點贊哦~歡迎大家關注我的部落格,可以進群366533258一起交流學習哦~