《剑指offer》面试题8旋转数组的最小值
一、什么是旋转数组?
旋转数组是把一个数组的开始的若干元素搬到数组的末尾,递增数组的旋转数组,将递增数组的开始的若干元素放置到数组的末尾,那么很显然数组前段部分中的每个元素都不小于后面那段中的每个元素。例如{1,2,3,4,5}旋转前两个元素后得到{3,4,5,1,2}。
二、基本方法
遍历数组找到第一个小于或者等于开头元素的位置,即使旋转数组的最小值,时间复杂度为O(n)。
三、二分法
开头元素位置为index1,末尾元素为index2,则只要numbers[index1]>=numbers[index2]则indexmid=(index1+index2)/2指导index2-index1==1,如果numbers[indexmid]>=numbers[index1]则说明在前一个递增段中,故index1=indexmid,如果numbers[indexmid]<=numbers[index2],则说明在后一个递增段中,故:index2=indexmid.
bug1:当出现numbers[index1]==numbers[index2]==numbers[indexmid]的时候会出现问题,这时候这种有基本方法。如{1,0,1,1,1}
四、code
#include <iostream> #include <exception> using namespace std; int mininorder(int *number,int index1,int index2); int min(int * numbers, int length){ if (numbers ==NULL||length<=0) { throw exception("Invaild parameters"); } int index1=0; int index2=length-1; int indexmid=index1; while (numbers[index1]>=numbers[index2]) { if (index2-index1 ==1) { indexmid=index2; break; } indexmid=(index1+index2)/2; if(numbers[index1]==numbers[index2]&&numbers[index1]==numbers[indexmid]) return mininorder(numbers,index1,index2); if(numbers[indexmid]>=numbers[index1]) index1=indexmid; else if(numbers[indexmid]<=numbers[index2]) index2=indexmid; } return numbers[indexmid]; } int mininorder(int * numbers,int index1,int index2){ int result=numbers[index1]; for (int i=index1+1;i<=index2;i++) { if(result>numbers[i]){ result=numbers[i]; } return result; } } int main(){ int numbers[]={3,4,5,1,2}; int length=sizeof(numbers)/sizeof(int); cout<<"In [3,4,5,1,2], the min is :"<<min(numbers,length)<<endl; int numbers2[]={1,0,1,1,1}; int length2=sizeof(numbers2)/sizeof(int); cout<<"In [1,0,1,1,1], the min is :"<<min(numbers2,length2)<<endl; }