【劍指offer】【08】旋轉數組的最小數字

題目描述

把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。

注意點

1:數組長度爲0時
2:數組非遞減,例如{0,1,1,1,1}->{1,1,0,1,1}
3:數組元素是否全部旋轉

解題思路

思路1:找出數組中最小的數字
思路2:順序查找,比較大小,找到臨界點
思路3:利用二分法,找到最小的數字


import java.util.Arrays;

/**
 * 旋轉數組的最小數字 
 * 1,數組長度爲0 
 * 2,數組非遞減{0,1,1,1,1}->{1,1,0,1,1},{1,1,1,1}->{1,1,1,1}
 * 3,數組元素是否全部旋轉
 * 
 * @author admin
 */
public class test08 {

	public static void main(String[] args) {

		int[] arr = { 5, 4, 3, 2, 1 };
		int min = minNumberInRotateArray2(arr);
		System.out.println(min);
	}

	// 既然是非遞減的,可以利用排序直接找到最小的數字,顯然這道題的初衷並不是考這個。。
	public static int minNumberInRotateArray3(int[] array) {
		if (array == null || array.length == 0) {
			return 0;
		}
		Arrays.sort(array);
		return array[0];
	}

	// 複雜度爲O(n)的方法,也是大多數人容易想到的方法,順序查找,比較大小,找到臨界點即可
	public static int minNumberInRotateArray(int[] array) {
		if (array == null || array.length == 0) {
			return 0;
		}
		int len = array.length;
		for (int i = 0; i < len - 1; i++) {
			if (array[i] > array[i + 1]) {
				return array[i + 1];
			}
		}
		return array[0];
	}

	// 複雜度爲O(log(n))的方法,利用二分法思想查找,逐步縮小查找範圍(!圈重點)
	public static int minNumberInRotateArray2(int[] array) {
		if (array == null || array.length == 0) {
			return 0;
		}
		int left = 0;
		int right = array.length - 1;
		int mid = 0;
		while (left < right) {
			mid = left + (right - left) / 2;
			if (array[mid] > array[right]) {
				left = mid + 1;
			} else if (array[mid] == array[right]) {
				right = right - 1; // [1,0,1,1,1]
			} else {
				right = mid;
			}
		}
		return array[left];
	}
}
//關於mid=(low+high)/2與mid=low+(high-low)/2的區別
//這兩種寫法雖然效果一樣,但是mid=low+(high-low)/2可以防止加法溢出。

 

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