算法笔记_128:完美洗牌算法(Java)
目录
1 问题描述
有一个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后变成{a1,b1,a2,b2,a3,b3,...,an,bn},请考虑有没有时间复杂度为O(n)而空间复杂度为O(1)的解法。
2 解决方案
2.1位置置换算法
下面算法的时间复杂度为O(n),空间复杂度为O(n)。
具体代码如下:
package com.liuzhen.practice;
public class Main {
//对于数组A第i个位置的元素都最终换到了2*i % len的位置
public void getLocationReplace(String[] A) {
int len = A.length;
String[] temp = new String[len];
for(int i = 1;i < len;i++)
temp[(2 * i) % len] = A[i];
for(int i = 1;i < len;i++)
A[i] = temp[i];
for(int i = 1;i < len;i = i + 2) {
String a1 = A[i];
A[i] = A[i + 1];
A[i + 1] = a1;
}
return;
}
public static void main(String[] args) {
Main test = new Main();
String[] A = {"", "a1", "a2", "a3", "a4", "a5", "b1", "b2", "b3", "b4", "b5"};
test.getLocationReplace(A);
for(int i = 1;i < A.length;i++)
System.out.print(A[i]+" ");
}
}
运行结果:
a1 b1 a2 b2 a3 b3 a4 b4 a5 b5
2.2 走环算法
下面算法的时间复杂度为O(n),空间复杂度为O(1)。
具体代码如下:
package com.liuzhen.practice;
public class Main1 {
public void CycleLeader(String[] A, int start, int mod) {
for(int i = start * 2 % mod;i != start;i = i * 2 % mod) {
String temp = A[i];
A[i] = A[start];
A[start] = temp;
}
return;
}
public void Reverse(String[] A, int start, int end) {
while(start < end) {
String temp = A[start];
A[start++] = A[end];
A[end--] = temp;
}
return;
}
public void RightRotate(String[] A, int start, int m, int n) {
Reverse(A, start + m + 1, start + n);
Reverse(A, start + n + 1, start + n + m);
Reverse(A, start + m + 1, start + n + m);
return;
}
public void PerfectShuffle(String[] A) {
int len = A.length;
int n = (len - 1) / 2;
int start = 0;
while(n > 1) {
//第1步:找到2*m = 3^k - 1,使得3^k <= len - 1 < 3^(k + 1)
int k = 0, m = 1;
for(;(len - 1) / m >= 3;k++, m = m * 3);
m = m / 2;
//第2步:把数组中的A[m + 1,...,n + m]那部分循环右移m位
RightRotate(A, start, m, n);
//第3步:对于长度为2*m的数组,刚好有k个圈,每个圈的头部为3^i
for(int i = 0, t = 1;i < k;i++, t = t * 3)
CycleLeader(A, t, m * 2 + 1);
//第4步:对数组后面部分A[2m + 1,...,2n]继续递归上面3步
start = start + m * 2;
n = n - m;
}
//n == 1时
String temp = A[1 + start];
A[1 + start] = A[2 + start];
A[2 + start] = temp;
for(int i = 1;i < len;i = i + 2) {
String a1 = A[i];
A[i] = A[i + 1];
A[i + 1] = a1;
}
return;
}
public static void main(String[] args) {
Main1 test = new Main1();
String[] A = {"", "a1", "a2", "a3", "a4", "a5", "b1", "b2", "b3", "b4", "b5"};
test.PerfectShuffle(A);
for(int i = 1;i < A.length;i++)
System.out.print(A[i]+" ");
}
}
运行结果:
a1 b1 a2 b2 a3 b3 a4 b4 a5 b5
参考资料:
1.《编程之法面试和算法心得》 July著
算法笔记_128:完美洗牌算法(Java)的更多相关文章
- Java实现完美洗牌算法
1 问题描述 有一个长度为2n的数组{a1,a2,a3,-,an,b1,b2,b3,-,bn},希望排序后变成{a1,b1,a2,b2,a3,b3,-,an,bn},请考虑有没有时间复杂度为O(n)而 ...
- [转]完美洗牌(Perfect Shuffle)问题
[转]原博文地址:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.09.md ...
- 《Algorithms算法》笔记:元素排序(3)——洗牌算法
<Algorithms算法>笔记:元素排序(3)——洗牌算法 Algorithms算法笔记元素排序3洗牌算法 洗牌算法 排序洗牌 Knuth洗牌 Knuth洗牌代码 洗牌算法 洗牌的思想很 ...
- knuth洗牌算法
首先来思考一个问题: 设计一个公平的洗牌算法 1. 看问题,洗牌,显然是一个随机算法了.随机算法还不简单?随机呗.把所有牌放到一个数组中,每次取两张牌交换位置,随机 k 次即可. 如果你的答案是这样, ...
- 洗牌算法Fisher_Yates原理
1.算法 http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 简单的原理如下图所示: 2.原理 总结下,洗牌算法Fisher_Yates ...
- C# 洗牌算法
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 C#洗牌算法如下: class Program { ...
- js 随机数 洗牌算法
function shuffle(arr){ var len = arr.length; for(var i = 0;i<len -1;i++) { var idx = Math.floor(M ...
- Fisher–Yates shuffle 洗牌算法(zz)
1,缘起 最近工作上遇到一个问题,即将一组数据,比如[A,B,C,D,E]其中的两个B,E按随机排列,其他的仍在原来的位置: 原始数组:[A,B,C,D,E] 随机字母:[B,D] 可能结果:[A,B ...
- 519. Random Flip Matrix(Fisher-Yates洗牌算法)
1. 问题 给定一个全零矩阵的行和列,实现flip函数随机把一个0变成1并返回索引,实现rest函数将所有数归零. 2. 思路 拒绝采样 (1)先计算矩阵的元素个数(行乘以列),记作n,那么[0, n ...
随机推荐
- [SPOJ SEQN] [hdu3439]Sequence
题目就是求C(n,k)*H(n - k)%m 0<= k<= n <=10^9, 1 <= m <= 10^5, n != 0 其中H(n)是错排第n项. 对于C(n,k ...
- codevs 5294 挖地雷
5294 挖地雷 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个地图上有N个地窖(N<=20),每个地窖中埋有一 ...
- 欧拉回路 uoj117
写了一道欧拉回路的模板题.先判断是否是欧拉回路,有向图和无向图有一点点不同,然后就是特判独立点的存在. 之后是输出路径,和dls学的dfs,利用last数组的更新可以做到线性的复杂度,否则一不小心就会 ...
- 「CSA72」MST
「CSA72」MST 题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改, ...
- 【离散化】【DFS】Gym - 101617H - Security Badges
题意:给你一张有向图,每条边有个限制范围,只有权值在限制范围内的人能走这条边,问你权值不超过K的人中,有多少人能从S到T. K很大,因此我们只处理边的范围的上下界这O(m)个权值能否到达,以防万一,还 ...
- 【8.28校内测试】【区间DP】
感受到了生活的艰辛QAQ...这才是真正的爆锤啊...(因为t1t3还没有理解所以只能贴t2叻QAQ 区间DP...爆哭把题理解错了,以为随着拿的东西越来越多,断点也会越来越多,出现可以选很多的情况Q ...
- 洛谷P4009 汽车加油行驶问题
题目描述 给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示. 一辆汽车从起点◎出发 ...
- XPath教程
XPath 简介 XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历. XPath 是 W3C XSLT 标准的主要元素,并且 XQuery ...
- 搭建windows server 2008 r2 FTP 后 开启防火墙无法访问的解决办法
转自http://kkworms.blog.51cto.com/540865/558477 今天在windows server 2008 R2上安装了FTP,安装过程如下,然后添加内置防火墙设置,设置 ...
- 【JSP EL】EL表达式里日期按照格式显示
转:http://blog.csdn.net/kaishuaige/article/details/8505174 JSP页面用EL表达式 输出date格式 1.头上引入标签 <%@ t ...