完美洗牌算法

本文介绍了完美洗牌算法,从2004年Peiyush Jain的论文出发,探讨了如何在数组中实现原址洗牌,通过环操作和循环左移解决了非特定长度数组的洗牌问题,同时提供了O(n)时间和O(1)空间复杂度的解决方案。
摘要由CSDN通过智能技术生成
部分内容转载自:http://blog.csdn.net/sunnyyoona/article/details/43795243,代码重新使用C++实现。

题目

玩过扑克牌的朋友都知道,在一局完了之后洗牌,洗牌人会习惯性的把整副牌大致分为两半,两手各拿一半对着对着交叉洗牌,我们的问题是:如何才能保证依次洗牌过后左右手牌是一一交叉的呢?

2004年,microsoft的Peiyush Jain在他发表一篇名为:“A Simple In-Place Algorithm for In-Shuffle”的论文中提出了完美洗牌算法。

什么是完美洗牌问题呢?即给定一个数组a1,a2,a3,…an,b1,b2,b3..bn,最终把它置换成b1,a1,b2,a2,…bn,an。

对原始位置的变化做如下分析:
这里写图片描述

依次考察每个位置的变化规律:

a1:1 -> 2 
a2:2 -> 4 
a3:3 -> 6 
a4:4 -> 8 
b1:5 -> 1 
b2:6 -> 3 
b3:7 -> 5 
b4:8 -> 7

对于原数组位置i的元素,新位置是(2*i)%(n+1),注意,这里用2n表示原数组的长度。后面依然使用该表述方式。有了该表达式,我们可以新建一个数组,然后遍历每一个元素&#x

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值