題目:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之為數組的旋轉。輸入一個遞增的排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如輸入{1,2,3,4,5}的一個旋轉為{3,4,5,1,2},該數組的最小值為1。
分析
最直觀的想法就是順序遍歷一次數組,就能夠找出最小的數字,這樣的時間復雜度是O(n),當時我也是這么跟面試官說的,我說遍歷一次不就OK了嗎?面試官說“如果你覺得遍歷一次是你覺得最好的,那就跟我說!”我立馬說不是的,讓我想想,應該還有其他更有的方法。是的,既然叫做旋轉數組,那么我們就需要利用好旋轉數組的特性。看到這樣的旋轉數組查找最小數,我們會不會潛意識里面就想到了二分查找呢。確實,這道題目就是用二分查找的思路來解決,中間用到了旋轉數組的一些特性。以題目中的旋轉數組為例,{3,4,5,1,2},我們可以有序數組經過旋轉以后被分割為兩段有序的數組,比如此處被分為{3,4,5}{1,2}這樣連個數組,並前前半段數組中的數字肯定大於等於后半段的數組。我們找中間元素,讓其跟元素首元素比較,如果大於首元素,則中間元素屬於前半段有序數組,如果小於尾元素,那么中間元素就是后半段的元素。
這里我們設定兩個指針start和end分別指向數組的首尾元素,然后當start指向前半段最后一個元素,end指向后半段第一個元素,這是程序就找到了數組中的最小元素,就是end指向的那個數,程序的出口就是 end-start==1。
下面的代碼示例中寫了兩個方法,第一個方法是返回最小元素在數組中的位置,如果輸入錯誤則返回-1;第二個方法是直接返回數組中的最小元素。
代碼實例

#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"); }