必威体育Betway必威体育官网
当前位置:首页 > IT技术

洗牌算法

时间:2019-10-03 15:45:40来源:IT技术作者:seo实验室小编阅读:52次「手机版」
 

洗牌算法

洗牌算法

洗牌算法是常见的随机问题:将1 ~ 52张扑克牌重新洗牌

什么是好的洗牌算法:洗牌之后,如果能够保证每一个数出现在所有位置上的概率是相等的,那么这种算法是符合要求的;这在个前提下,尽量降低时间和空间复杂度。

第一个算法:

随机抽出一张牌,检查这种牌是否被抽取过,如果已经被抽取过,则重新抽取,知道找到没有被抽取的牌;重复该过程,知道所有的牌都被抽取到。

这种算法是比较符合大脑的直观思维,这种算法有两种形式:

1. 每次随机抽取后,将抽取的牌拿出来,则此时剩余的牌为(N-1),这种算法避免了重复抽取,但是每次抽取一张牌后,都有一个删除操作,需要在原始数组中删除随机选中的牌(可使用Hashtable实现)

2. 每次随机抽取后,将抽取的符合要求的牌做好标记,但并不删除;与1相比,省去了删除的操作,但增加了而外的存储标志为的空间,同时导致可每次可能会抽取之前抽过的牌

这种方法的时间/空间复杂度都不好。

第二个算法:

每次随机抽出两张牌交换,交换一定次数后结束:

这是一个常见的洗牌算法; 但是如何确定一个合适的交换次数?

假设交换了m此,则某张牌始终没有被交换的概率为 (n-2)/n * (n-2)/n, ... ...* (n-2)/n = ((n-2)/n)^m;我们希望其概率小于摸个值,求出m的解.假设概率小于1/1000,对于n=52,m大概为176,实际上远远大于数组的长度.

第三个算法:

Fisher–Yates随机置乱算法也被称做高纳德置乱算法,通俗说就是生成一个有限集合的随机排列。Fisher-Yates随机置乱算法是无偏的,所以每个排列都是等可能的,当前使用的Fisher-Yates随机置乱算法是相当有效的,需要的时间正比于要随机置乱的数,不需要额为的存储空间开销。

class Solution {
public:
	vector<int> shuffle(vector<int> a) {
		int n = a.size();
		for (int i = n - 1; i >= 0; i--)
			swap(a[i], a[rand() % (i + 1)]);
		return a;
		}
};
该算法每次随机选取一个数,然后将该数与数组中最后的元素相交换(如果随机选中的是最后的元素,则相当于没有发生交换);然后缩小选取数组的范围,去掉最后的元素,即之前随机抽取出的数。重复上面的过程,直到剩余数组的大小为1,即只有一个元素时结束。

相关阅读

贪心算法(一)

概念:贪心法,指的是从问题的初始状态出发,通过若干次的贪心选择而得出最优值(或较优解)的一种解题方法。其实,从“贪心策略”一词我们

常见的hash算法及其原理

 Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输

银行家算法

先假设系统中的进程有P个,资源有R种,我们要定义如下数组(或二位数组)1. Available Available是一个数组,它的长度等于R,也就是和资

meanshift算法通俗讲解

这几天学习《学习OpenCV》中的第十章运动跟踪,里面讲到了meanshift算法,根据书上所讲实在难以理解,meanshift在运动跟踪这个过程中到

算法 BF算法

BF算法是字符匹配的一种算法,也称暴力匹配算法算法思想:从主串s1的pos位置出发,与子串s2第一位进行匹配若相等,接着匹配后一位字符若

分享到:

栏目导航

推荐阅读

热门阅读