随机算法入门:洗牌算法
洗牌算法是什么?
其实就理解为生成一个随机数列的一个简单操作而已。
怎么生成?
我们先讲下一般我们会想到的一个解法——标记。
怎么标记呢?
假设我们的数组为a,ai 代表数组a第i个数。
一个布尔数组b(其他类型的数组也行)。
然后把a数组下标作为状态空间进行随机生成,接着把生成过的数下标 i 用 bi =1表示为已出现过,用 bi==0表示为未出现过.
如果前面出现过的数则重新随机。
问题来了:这样的复杂度是多少?——会是n2的复杂度,如果平均下来也是n log n
所以怎么处理这个问题?
如果你想删除当前数的话——删除会导致数组整体向后移动啊!
相信大家都学过二叉堆(没学过也没事),更新数值时我们会把堆顶放在堆末尾,然后再UP,DOWN操作一遍。
类比一下——这样避免了整个数组的往后移动。
假设最初数组里1~N个数需要随机,目前随机范围为N
所以我们可以生成完当前数后,把这个数和最后一个数交换,然后随机下标范围变为N-1
以此循环即可。