洗牌算法
一、最朴素的算法
首先先考虑要求,正常来说洗牌,就是保证每一个位置出现每一张牌的概率是一样的。有n张牌,任何一种系列出现的概率应该是1/(n!)
思路:
- 初始化原始数组和新数组,原始数组长度为n(已知);
- 从还没处理的数组(假如还剩k个)中,随机产生一个[0, k)之间的数字p(假设数组从0开始);
- 从剩下的k个数中把第p个数取出;
- 重复步骤2和3直到数字全部取完;
- 从步骤3取出的数字序列便是一个打乱了的数列。
时间复杂度O(n*n) 空间复杂度O(n)
二、经典洗牌算法
思路:在原数组尾部开始,记索引为i,产生一个0-i的数 (不是i-1).然后个第i个互换。
def fun(n):
for i in range(1000000):
l = [i for i in range(n)]
for i in range(n - 1, 0, -1):
j = random.randint(0, i)
l[i], l[j] = l[j], l[i]
return l