算法:完美洗牌算法:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn
来源:互联网 发布:淘宝模特网拍培训 编辑:程序博客网 时间:2024/05/11 03:59
问题描述:一个长度为2n的数组元素为 a1 a2 ... an b1 b2 ... bn
要求: 用O(1)的空间代价, 在O(n)时间内把数组变成 b1 a1 b2 a2 b3 a3 ... bn an (分治法时间复杂度O(nlogn))
要求: 用O(1)的空间代价, 在O(n)时间内把数组变成 b1 a1 b2 a2 b3 a3 ... bn an (分治法时间复杂度O(nlogn))
采取置换的方法,当需要保证似乎循环无遗漏置换。需要用到数论原根等证明定理。
http://user.qzone.qq.com/414353346/blog/1243343118#!app=2&via=QZ.HashRefresh&pos=1243343118
算法论文:http://arxiv.org/pdf/0805.1598.pdf
自己的算法实现:
int static findMaxNear(int length){int k=3;while(k-1<length) k*=3;if(k-1==length)return k-1;elsereturn k/3 - 1;}void reverse(int a[],int start,int end){for(int i=start,j=end;i<j;i++,j--){int tmp=a[i];a[i]=a[j];a[j]=tmp;}}void rightmove(int a[],int start,int end,int steps){reverse(a,start,end);reverse(a,start,start+steps-1);reverse(a,start+steps,end);}void static shuffle_3k(int a[],int start,int length){int cyclestart=1; //3^0while(cyclestart<=length){ //length==3^k-1,cyclestart=1,3^1,...,3^(k-1)int tmp=a[start+cyclestart-1],nexttmp;int nextpos=2*cyclestart%(length+1); //nextpos为当前元素移动到的位置while(nextpos!=cyclestart){ //直到回到起点nexttmp=a[start+nextpos-1];a[start+nextpos-1]=tmp;tmp=nexttmp; nextpos=nextpos*2%(length+1);}a[start+cyclestart-1]=tmp;cyclestart*=3;}}void perfect_shuffle(int a[],int start,int length){int startpos=start,end=start+length-1;while(startpos-start<length){int cur_length=end-startpos+1;int m=findMaxNear(cur_length);//i=3^k-1<=Nif(m<cur_length) //还有剩余序列,则需要循环右移m/2个单位rightmove(a,startpos+m/2,startpos+cur_length/2+m/2-1,m/2);shuffle_3k(a,startpos,m);//分别以1,3,9,...,3^k为首元素开始循环置换startpos+=m;}}#define N 100void main(){int data[N]={0};int i=0;int n;printf("please input the number of data you wanna to test(should less than 100):\n");scanf("%d",&n);if(n&1){printf("sorry,the number should be even ");return;}for(i=0;i<n;i++)data[i]=i+1;perfect_shuffle(data,0,n); //in perfect_shuffle 首位均改变for(i=0;i<n;i++)printf("%d ",data[i]);}
输入:10
即: 1 2 3 4 5 6 7 8 9 10
输出: 6 1 7 2 8 3 9 4 10 5
- 算法:完美洗牌算法:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn
- 问题描述:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn 要求: 用O(1)的空间代价, 在O(n)时间内把数组变成 a1 b1 a2 b2 a3 b3 ... an bn
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn )
- 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn ) 概论思想(perfect shuffle 算法)
- a1,a2,...,an,b1,b2,...,bn,
- 行车(a1*b1+a1*b2+..a1*bn+a2*b1+...an*bn=(a1+..an)(b1+..bn) )
- 拆分单链表(a1,b1,a2,b2....an,bn)=(a1,...an)+(bn,...b1)
- 输入a1,a2,...,an,b1,b2,...,bn, 将这个序列顺序改为a1,b1,a2,b2,a3,b3,...,an,bn
- 有一个带头结点的单链表L={a1,b1,a2,b2,...,an,bn},设计一个算法将其拆分成两个带头结点的单链表A和B,正序链表A={a1,a2,a3...,an},逆序链表B={bn,bn-1,
- 据说是G开头公司的面试题【输入a1,a2,...,an,b1,b2,...,bn】
- 设以带头结点的双向循环链表表示的线性表L= (a1,a2,…,an),试写一时间复杂度O(n)的算法,将L改造为 (a1,a3,…,an,…,a4,a2)。
- 求一个长度为n的整型有序数组中是否有出现次数超过n/2的元素
- 有序整型数组A,大小为n,请给出一个O(n)的算法,删除重复元素,O(1)空间
- 面试-链表逆置 作业手写一个单链表,并且实现单链表元素的逆置,(a0, a1,a2,a3,..an)-> (an,an-1,… a1, a0),算法的空间复杂度和时间复杂度经可能低
- c#计算两个时间段(DateTime A1,DateTime A2)-(DateTime B1,DateTime B2)之间重复的时间
- (A1^B1+A2^B2+ ... +AH^BH)mod M.
- MyEclipse8.6反编译配制
- C++编程模板(头文件 + 常用函数)
- 华宰 adnroid 3D 系列之基本概念篇!!!!!!!!!!!
- 僵尸网络为云计算所用
- Ecmall商品添加将品牌改为选择式
- 算法:完美洗牌算法:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn
- OpenGL扩库内存泄漏
- acm 拼成最小的数
- IPC 手机客户端
- 程序员你伤不起的一些谬论
- E: Sub-process /usr/bin/dpkg returned an error code (1)错误解决
- 电子书下载:Delphi XE2 入門指引手冊
- Qt学习笔记4-Widget布局管理
- Fedora5下skyeye安装相关