1. 程式人生 > >劍指Offer(第二版)面試題11:旋轉陣列的最小數字

劍指Offer(第二版)面試題11:旋轉陣列的最小數字

劍指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:利用旋轉陣列部分有序的特點,進行二分查詢,減小時間複雜度。注意特殊情況的處理。
/**
	 * 利用二分查詢的思想,時間複雜度為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;
	}
在上面的演算法中,當前面的若干個元素是指0個元素旋轉到後邊時,mid=0,則不會進入while迴圈,直接返回arr[0],即是陣列中的最小值。

反之進行二分查詢,根據條件變化左右指標,直到兩個指標相鄰。

特殊情況:前、後以及mid指標所指向的數均相同,則不能判斷該如何移動前後指標,此時,必須在前後指標範圍內使用順序查詢來搞定。

如果對你有幫助,記得點贊哦~歡迎大家關注我的部落格,可以進群366533258一起交流學習哦~