題目:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如{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;
}
}