1、題目描述java
Suppose a sorted array is rotated at some pivot unknown to you beforehand.ios
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).數組
Find the minimum element.spa
You may assume no duplicate exists in the array.設計
2、分析指針
這題難度有,由於他默認的是數組中全部的元素是不一樣的。只有分爲兩種狀況:
code
一、數組中全部的元素單調遞增(0 1 2 4 5 6 7)blog
二、有個旋轉點的(4 5 6 7 0 1 2),那就要根據中間值的位置判斷是在前面的遞增序列中仍是後面的遞增序列中排序
3、設計思路element
一、 設置兩個指針,初始狀態第一個指針指向前面子數組的第一個元素,第二個指針指向後面子數組的最後一個元素;
二、 找到兩個指針的中間元素;
三、若其大於等於第一個指針指向的元素,則說明其在前面的子數組中,且顯然最小元素在中間元素的右邊,若其小於等於第二個指針指向的元素,則說明其在後面的子數組中,且顯然最小元素在中間元素的左邊。
package com.edu.leetcode; public class FindMinimuminRotatedSortedArray { public int findMin(int[] num) { if(num.length==1){ return num[0]; } int i=0; int j=num.length-1; int mid=0; if(num[i]<num[j]){ //單調遞增的狀況 return num[0]; } else{ //有拐點的狀況 while(i+1!=j){ mid=(i+j)/2; if(num[mid]>num[i]){ //說明mid的位置在前面的遞增序列中 i=mid; } if(num[mid]<num[j]){ //說明mid的位置在後面的遞增序列中 j=mid; } } return num[j]; } } public static void main(String[] args) { // TODO Auto-generated method stub FindMinimuminRotatedSortedArray f= new FindMinimuminRotatedSortedArray(); int[] num={4,5,6}; System.out.println(f.findMin(num)); } }
3、難度提高--當容許有重複的元素時
分析:
第一種解法:暴力求解--遍歷整個數組,獲得最小值
第二種解法:對半查找--思路跟上面大體相同,但不一樣是的當i,mid和j位置三個元素都相等時,沒辦法在使用對半方法,只能遍歷整個數組
#include<iostream> #include<stdlib.h> #include<stack> using namespace std; int min(int arry[],int len)//返回最小數的座標 { if(arry==NULL||len<=0) return -1; int start=0; int end=len-1; while(start<end) { //若是首個元素小於最後一個元素,代表數組是排序的。 if(arry[start]<arry[end]) return start; //當start指針和end指針隔壁的時候,返回end指針就是最小元素的座標 if(end-start==1) return end; int mid=(start+end)/2; //若是arry[mid],arry[start]和arry[end]三個數相等,就只能使用順序查找 if(arry[mid]==arry[start]&&arry[mid]==arry[end]) { int index=start; for(int i=start+1;i<=end;i++) { if(arry[i]<arry[index]) index=i; } return index; } //若是中間元素小於末尾元素,那麼代表中間元素在後半段數組中,修改end指針 if(arry[mid]<arry[end]) { end=mid; } //若是中間元素大於首元素,那麼代表中間元素在前半段數組中,修改start指針 else if(arry[mid]>arry[start]) { start=mid; } } return -1; } int minNum(int arry[],int len)//返回最小數的值 { if(arry==NULL||len<=0) throw exception("非法輸入"); int start=0; int end=len-1; while(arry[start]>=arry[end]) { if(end-start==1)//若是start和end相差1則返回arry[end] return arry[end]; int mid=(start+end)/2; //若是arry[mid],arry[start]和arry[end]三個數相等,就只能使用順序查找 if(arry[mid]==arry[start]&&arry[mid]==arry[end]) { int result=arry[start]; for(int i=start+1;i<=end;i++) { if(arry[i]<result) result=arry[i]; } return result; } if(arry[mid]>=arry[start])//若是中間元素大於首元素,則移動首指針 { start=mid; } else if(arry[mid]<=arry[end]) { end=mid; } } return arry[start];//若是一開始arry[start]<arry[end]代表數組是排序數組,返回arry[start] } void main() { int arry[]={1,0,1,1,1}; int len=sizeof(arry)/sizeof(int); int index=min(arry,len); int minnum=minNum(arry,len); cout<<"最小數在數組中的位置:"<<index<<endl; cout<<"最小數的值:"<<minnum<<endl; system("pause"); }