完美洗牌&洗牌
完美洗牌问题,给定一个数组a1,a2,a3,...an,b1,b2,b3..bn,把它最终设置为b1,a1,b2,a2,...bn,an这样的。
O(n)的算法,O(n)的空间。
对于前n个数,映射为f(i)=2 * i + 1, 0 <= i < n / 2; 比如0->1, 1->3
对于后n个数,映射为f(i)=2(i - n/2), n / 2 <= i < n; 比如n/2->0, n/2 + 1->2... 并且f(i) =2(i - n/2)=2*i-n=2*i+1-(n+1)=(2*i+1)%(n+1)。
统一起来,映射为f(i) = (2 * i + 1) % (n + 1).
void perfectShuffle1(int arr[], int n) {
int* tmp = new int[n];
for (int i = ; i < n; ++i) {
tmp[((i << ) + ) % (n + )] = arr[i];
}
for (int i = ; i < n; ++i) {
arr[i] = tmp[i];
}
delete[] tmp;
}
分治法,O(nlgn)的算法,O(lgn)的空间。
Line 4-11 主要就是处理好数组的一半为奇数的情部分。
当n/4!=0的时候,数组的一半为奇数。此时要将[n/2,n)的数往左移,把第n/2-1个数(前一半的最后一个数)放到末尾,这样,最后两个数就排好了。问题就转化成了数组的一半是偶数的情况。
当数组的一半是偶数时,只需要把前一半的后半部分和后一半的前半部分交换一下,就达到分治的目的了。
void perfectShuffle2(int arr[], int n) {
if (n % != ) return;
if (n <= ) return;
if (n % != ) {
int tmp = arr[n / - ];
for (int i = n / ; i < n; ++i) {
arr[i - ] = arr[i];
}
arr[n - ] = tmp;
n -= ;
}
for (int i = ; i < n / ; ++i) {
swap(arr[n / + i], arr[n / + i]);
}
perfectShuffle2(arr, n / );
perfectShuffle2(arr + n / , n / );
}
主要参考自:http://blog.csdn.net/caopengcs/article/details/10176093, 里面提到的第三种解法没去看,感觉面试不会考就先不费力去理解了。
洗牌的问题就比较简单,其实相当于从数组中随机选出m个数,见之前的博文。只不过这里m=n而已。
void shuffle(int arr[], int n) {
srand(time(NULL));
for (int i = ; i < n; ++i) {
swap(arr[i], arr[i + rand() % (n - i)]);
}
}
这个和网上提到的FisherYates洗牌算法的原理是一样的。
完美洗牌&洗牌的更多相关文章
- 实现纸牌游戏的随机抽牌洗牌过程(item系列几个内置方法的实例)
实现纸牌游戏的随机抽牌洗牌过程(item系列几个内置方法的实例) 1.namedtuple:命名元组,可以创建一个没有方法只有属性的类 from collections import namedtup ...
- Java基础知识强化之集合框架笔记71:模拟斗地主洗牌和发牌并对牌进行排序的案例
1. 模拟斗地主洗牌和发牌并对牌进行排序的原理图解: 2. 代码实现: 思路: • 创建一个HashMap集合 • 创建一个ArrayList集合 • 创建花色数组和点数数组 • 从0开始往HashM ...
- 闲话shuffle(洗牌)算法
工作中经常会用到洗牌算法,看到这篇文章不错,原文摘自:http://www.atatech.org/article/detail/11821/928 作者:子仲 场景 洗牌算法的应用场景其实很多 ...
- VB洗牌算法产生随机数组
算法图示: 运行效果: 详细代码: Option Explicit '洗16张牌(0-15),方便用十六进制显示 Dim Card() As Long Private Sub 洗牌() Dim i&a ...
- Java模拟斗地主发牌和洗牌
package cn.itcast_04; import java.util.ArrayList; import java.util.Collections; import java.util.Has ...
- 《Algorithms算法》笔记:元素排序(3)——洗牌算法
<Algorithms算法>笔记:元素排序(3)——洗牌算法 Algorithms算法笔记元素排序3洗牌算法 洗牌算法 排序洗牌 Knuth洗牌 Knuth洗牌代码 洗牌算法 洗牌的思想很 ...
- 实现斗地主纸牌游戏---洗牌 发牌 看底牌的具体功能------Map集合存储方法 遍历的应用
该Demo只是斗地主的游戏的一部分,实现的斗地主的组合牌 洗牌 发牌 看牌的功能,主要应用Map集合进行练习 package cn.lijun import java.util.ArrayList ...
- java斗地主扑克 扑克牌 洗牌 发牌 Collection 集合练习
package com.swift.poker; import java.util.ArrayList; import java.util.Collections; /*训练考核知识点:Collect ...
- Python洗牌算法重写
Python有自带的洗牌算法函数shuffle(). 自己也通过学习也琢磨了一下它的实现,然后给出一个时间复杂度O(n),空间复杂度O(4)的例子: import random def shuffle ...
随机推荐
- web开发中目录路径问题的解决
web开发当中,目录路径的书写是再常用不过了,一般情况下不会出什么问题,但是有些时候出现了问题却一直感到奇怪,所以这里记录一下,彻底解决web开发中路径的问题,开发分为前端和服务端,那么就从这两个方面 ...
- 用Navicat for oracle导入现有数据库
重要参考:http://www.admin5.com/article/20130420/499241.shtml 前期准备,参考另一篇随笔. 安装Oracle,PL/SQL, 新建表空间myTS,新建 ...
- jQuery过滤选择器
//基本过滤器$('li:first').css('background','#ccc');//第一个元素$('li:last').css('background','red');//最后一个元素$( ...
- sdut 2416:Fruit Ninja II(第三届山东省省赛原题,数学题)
Fruit Ninja II Time Limit: 5000MS Memory limit: 65536K 题目描述 Have you ever played a popular game name ...
- C# 编程音量控制
public FrmVoice() { InitializeComponent(); } [DllImport("user32.dll", EntryPoint = "S ...
- 用于Simple.Data的ASP.NET Identity Provider
今天推举的这篇文章,本意不是要推举文章的内容,而是据此介绍一下Simple.Data这个很有意思的类ORM工具. 现在大家在.NET开发中如果需要进行数据访问,那么基本都会使用一些ORM工具,比如微软 ...
- x264_param_t结构体参数分析
转自:http://blog.chinaunix.net/uid-17053077-id-1987955.html 参考网上的一些资料,结合个人的理解,对x264中x264_param_t结构体作了初 ...
- 兼容古董级IE小结
IE6已经死亡,当然7,8,9,10也挂掉了.微软对IE11更下了狠手,对其停止了更新.以为前端就可以安安心心地写代码了.可是就是有些顽固分子,竟然用的还是IE6,尊崇客户至上的原则,就恶心着给他兼容 ...
- [转]Android的Handler总结
一.Handler的定义: 主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线 ...
- loj 1185(bfs)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26898 思路:我们可以给定有直接边相连的两点的距离为1,那么就是求 ...