旋轉數組(循環數組)的最小數字

題目:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如:{3,4,5,1,2},{4,5,1,2,3}都是數組{1,2,3,4,5}的旋轉,該數組的最小值爲1。有相同數字的情況,如{1,0,1,1,1},{1,1,1,0,1}都可以看做是數組{0,1,1,1,1}的旋轉。

/*
 * 旋轉數組中的最小數字
 * 算法思想:二分查找的變型,設置兩個指針low,high分別指向數組的開頭與結尾。如果中間位置的數字大於low指向的數字,則low = mid;如果中間位置的數字小於high指向的數字,則high = mid;
 * 特殊情況:low high 以及中間的元素的值均相等,這時無法利用上述方法進行判斷,對數組按照順序查找即可。
 * */
public class RotateMin {
	public static int minNumberInRotateArray(int[] arr){
		int low = 0;   //從前往後走
		int high = arr.length - 1;  //從後往前走
		int mid = 0; 
		int min = arr[low];   //如果沒有發生旋轉,直接返回arr[0]
		while(arr[low] >= arr[high]){   
			if(high - low == 1){   //當兩個指針走到挨着的位置的時候,p2就是最小值
				min = arr[high];
				break;
			}
			mid = (low + high) >> 1;
			//如果中間元素的值,與首尾指針指向的數字相同,則進行順序查找即可
			if(arr[low] == arr[mid] && arr[mid] == arr[high]){
				min = minOrder(arr, low, high);
			}
			if(arr[low] <= arr[mid]){   //如果中間位置的數字位於數組1,讓low走到mid的位置
				low = mid;
			}else if (arr[high] >= arr[mid]) {   //若中間位置的數字位於數組2中,讓high走到mid的位置
				high = mid;
			}
		}
		return min;
	}
	
	public static int minOrder(int[] arr, int low,int high){
		int min = arr[low];
		for(int i = low + 1; i <= high; i++){
			if(arr[i] < min){
				min = arr[i];
			}
		}
		return min;
	}
	public static void main(String[] args) {
		int[] arr = {4,5,1,2,3};
		int[] arr1 = {1,1,1,0,1};
		System.out.println("旋轉數組中最小的數字是:" + minNumberInRotateArray(arr));
		System.out.println("有相同數字的旋轉數組中的最小數字是:" + minNumberInRotateArray(arr1));
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章