求旋转序列的最小值
来源:互联网 发布: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
- 求旋转序列的最小值
- 求旋转数组的最小值
- 求旋转数组的最小值
- 求序列的最大最小值
- 求旋转数组后的最小值
- Java求旋转数组的最小值
- 旋转数组求最小值
- 旋转数组求最小值
- 旋转数组求最小值
- 求旋转数组中的最小值
- 递归求序列最大最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- mysql中文乱码
- Winform读取Access数据库,并取数据装入DataSet
- BAT JavaScript前端笔试面试题及答案
- DS3500 重置管理密码
- 术语
- 求旋转序列的最小值
- MicroWrt开发环境搭建
- 有关管理客户需求的一点见解
- Android GridView 横向滚动 一行显示
- Oracle的常用命令之备份和恢复数据库
- jquery UI学习笔记-知问前端之验证表单插件
- Free Running Timer ?
- #include< >和#include“ ”的区别
- POJ 3041 Asteroids(最小点覆盖)