劍指offer(java)——在遞增旋轉數組中查找最小值

題目:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。

題目關鍵詞:遞增排序、旋轉。

分析:上圖是符合題目要求的三種數組,第一種是很正規的一種情況:數組因爲旋轉的原因,分成兩個遞增數組,而最小值位於後面數組的第一個值。針對此題,首先要想到的是採用二分查找,第二點非常重要的一點就是想到旋轉數組條件特殊的數組,加以處理。(一個好的開發人員應該要是一個好的測試人員)

上圖2是一個排好序的數組,是一種特殊的旋轉數組,對於此種情況,直接返回數組的第一個元素即可,代碼中體現爲mid的初始值爲start;上圖三如果start、end、mid對應的值相等的情況二分無法確定最小值在哪部分,此時可以採用順序查找。

package com.example;

public class FindMin {
	
	public static void main(String[] args) {
		int[] nums={6,7,8,1,2,3,4,5};//{1,0,1,1,1};//{1,2,3,4,5,6,7,8};//{3,4,5,1,2};
		int minNUm=findMin(nums);
		System.out.println("數組中最小的數"+minNUm);
	}
	/**
	 * 查找數組中的最小值
	 * @param nums 遞增排序的旋轉數組
	 * @return  數組中的最小值
	 */
	public static int findMin(int[] nums){
		//判空處理
		if(nums==null||nums.length<0){
			throw new IllegalArgumentException("輸入數組參數非法");
		}
		int start=0;//開始指針
		int end=nums.length-1;//結束指針
		int mid=start; //如果數組本來就是排好序的,則數組的第一個元素就是數組的最小值
		while(nums[start]>=nums[end]){
			if(end-start==1){//循環結束條件
				mid=end;
				break;
			}
			mid=(start+end)/2;
			//如果start,end,mid指向的數組相等,則只能是採用順序查找
			if(nums[start]==nums[end]&&nums[start]==nums[mid]){
				return minInOrder(nums,start,end);
			}
			
			if(nums[start]<=nums[mid]){
				start=mid;
			}else if(nums[end]>=nums[mid]){
				end=mid;
			}
		}
		return nums[mid];
	}

	private static int minInOrder(int[] nums, int start, int end) {
		int result=nums[start];
		for(int i=start+1;i<=end;i++){
			if(result>nums[i]){
				result=nums[i];
			}
		}
		return result;
	}
}

 

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