求旋转序列的最小值

来源:互联网 发布:90后网络女红人 编辑:程序博客网 时间:2024/05/21 09:17

一、问题描述:

设有非降序整数序列A=a1, a2, ..., an,则整数序列B=ak+1,..., an, a1,..., ak(1<=k<=n)是序列A的一个旋转序列,当k=n时序列B与序列A相同。给定一旋转序列a[0, 1, ..., n-1],求该序列的最小值。

二、问题求解:

直接二分法搜索。设头指针f,尾指针r,中间指针m=(f+r)/2,则有如下求解过程:

设f=0, r=n-1:

1. 若f小于r,则令m=(f+r)/2,转2;否则,返回a[f],算法结束;

2. 若a[m]大于a[r],则最小值指针pos必在m之后,此时应将f更新为m+1,转1;否则,最小值指针pos必在m或m之前,此时应将r更新为m,转1;

由于循环执行条件是f小于r,故每次循环后,必有f(变大)或r(变小)得到更新,故能保证算法结束。

三、代码实现:

各函数作用如下:

void swap(int &a,int &b);//交换变量a,b的值int cmp(const void *a,const void *b);//比较a,b所指单元的值的大小,并将数组a非递减排列;void reverse(int *a,int beg,int end);//将数组a的区间[beg,end]位置上的数据逆置;void init_arr(int *a,int n);//初始化数组a,随机生成数据,并将数组a非递减排列;void print_arr(int *a,int n);//打印数组a;int min_arr(int *a,int n);//寻找旋转序列中的最小值;void rotate_arr(int *a,int n,int k);//对数组a进行旋转,向右旋转k个单位;<pre name="code" class="cpp">#include<cstdio>#include<ctime>#include<cstdlib>#include<cassert>void swap(int &a,int &b);int cmp(const void *a,const void *b);void reverse(int *a,int beg,int end);void init_arr(int *a,int n);void print_arr(int *a,int n);int min_arr(int *a,int n);void rotate_arr(int *a,int n,int k);int main(int argc,char *argv[]){const int SIZE=20;int a[SIZE];init_arr(a,SIZE);print_arr(a,SIZE);printf("min:%d\n",min_arr(a,SIZE));rotate_arr(a,SIZE,5);print_arr(a,SIZE);printf("min:%d\n",min_arr(a,SIZE));return 0;}void swap(int &a,int &b){a^=b;b^=a;a^=b;}int cmp(const void *a,const void *b){return *(int*)a-*(int*)b;}void reverse(int *a,int beg,int end){while(beg<end){swap(a[beg++],a[end--]);}}void init_arr(int *a,int n){srand(time(NULL));for(int i=0;i<n;++i){a[i]=rand()%20;}qsort(a,n,sizeof(int),cmp);}void print_arr(int *a,int n){printf("##begin##\n");for(int i=0;i<n;++i){printf("%d ",a[i]);}printf("\n##end##\n");}int min_arr(int *a,int n){assert(a!=NULL&&n>0);int f=0,r=n-1,m;while(f<r){m=(f+r)>>1;if(a[m]>a[r]){f=m+1;}else{r=m;}}return a[f];}void rotate_arr(int *a,int n,int k){if(a==NULL||n<1||k<1||k>=n){return;}reverse(a,0,k-1);reverse(a,k,n-1);reverse(a,0,n-1);}

四、测试结果:<pre name="code" class="cpp">##begin##0 1 2 3 3 3 4 6 6 7 7 9 9 13 13 13 17 17 18 18##end##min:0##begin##3 4 6 6 7 7 9 9 13 13 13 17 17 18 18 0 1 2 3 3##end##min:0

0 0