劍指offer{面試題8:旋轉陣列的最小數字}
阿新 • • 發佈:2018-12-14
思路:還是設定兩個指標,一頭一尾,隨時變動指標,左半部分大指標往中間去,右半部分大指標前移, public class test08 {
/** * 把一個數組最開始的若干個元素搬到陣列的末尾, 我們稱之陣列的旋轉。 * 輸入一個遞增排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 * 例如陣列{3, 4, 5, 1, 2}為{l ,2, 3, 4, 5}的一個旋轉,該陣列的最小值為 * * @param numbers 旋轉陣列 * @return 陣列的最小值 */ public static int min(int[] numbers) { // 判斷輸入是否合法 if (numbers == null || numbers.length == 0) { throw new RuntimeException("Invalid input."); } // 開始處理的第一個位置 int lo = 0; // 開始處理的最後一個位置 int hi = numbers.length - 1; // 設定初始值 int mi = lo; // 確保lo在前一個排好序的部分,hi在排好序的後一個部分 while (numbers[lo] >= numbers[hi]) { // 當處理範圍只有兩個資料時,返回後一個結果 // 因為numbers[lo] >= numbers[hi]總是成立,後一個結果對應的是最小的值 if (hi - lo == 1) { return numbers[hi]; } // 取中間的位置 mi = lo + (hi - lo) / 2; // 如果三個數都相等,則需要進行順序處理,從頭到尾找最小的值 if (numbers[mi] == numbers[lo] && numbers[hi] == numbers[mi]) { return minInorder(numbers, lo, hi); } // 如果中間位置對應的值在前一個排好序的部分,將lo設定為新的處理位置 if (numbers[mi] >= numbers[lo]) { lo = mi; } // 如果中間位置對應的值在後一個排好序的部分,將hi設定為新的處理位置 else if (numbers[mi] <= numbers[hi]) { hi = mi; } } // 返回最終的處理結果 return numbers[mi]; } /** * 找陣列中的最小值 * * @param numbers 陣列 * @param start 陣列的起始位置 * @param end 陣列的結束位置 * @return 找到的最小的數 */ public static int minInorder(int[] numbers, int start, int end) { int result = numbers[start]; for (int i = start + 1; i <= end; i++) { if (result > numbers[i]) { result = numbers[i]; } } return result; } public static void main(String[] args) { // 典型輸入,單調升序的陣列的一個旋轉 int[] array1 = {3, 4, 5, 1, 2}; System.out.println(min(array1)); // 有重複數字,並且重複的數字剛好的最小的數字 int[] array2 = {3, 4, 5, 1, 1, 2}; System.out.println(min(array2)); // 有重複數字,但重複的數字不是第一個數字和最後一個數字 int[] array3 = {3, 4, 5, 1, 2, 2}; System.out.println(min(array3)); // 有重複的數字,並且重複的數字剛好是第一個數字和最後一個數字 int[] array4 = {1, 0, 1, 1, 1}; System.out.println(min(array4)); // 單調升序陣列,旋轉0個元素,也就是單調升序陣列本身 int[] array5 = {1, 2, 3, 4, 5}; System.out.println(min(array5)); // 陣列中只有一個數字 int[] array6 = {2}; System.out.println(min(array6)); // 陣列中數字都相同 int[] array7 = {1, 1, 1, 1, 1, 1, 1}; System.out.println(min(array7)); System.out.println(min(array6)); // 輸入NULL System.out.println(min(null)); } }