简介首先看一个主题:有一个大小为100的数组,其中的元素为1到100,并从该数组中随机选择50个唯一数字。使用Math.random()* 100,您可以获得0到99之间的随机数。是否足以重复50次?当然不是,如果第一次随机数为5,如果第二次随机数为5,则要求选择非重复数,因此,如果要选择50个非重复数,则随机数要大得多。而不是50。这是因为您到达后面的次数越多,随机获得的号码就越有可能与您先前选择的号码重复出现。怎么解决呢?每个人都玩过或看过发牌。共发行了54张牌。发一张卡。庄家会丢掉一张卡,直到所有卡都发完为止。上述问题也可以通过这种方式解决。达到第一个随机数后,将数字取出,然后从剩余的99个数字中随机取出第二个数字,以使随机取出50次的书不再重复,这是今天的主题:随机算法Fisher-Yates随机算法由Ronald A. Fisher和Frank Yates于1938年发明,后来由Knuth引入书中。许多人直接将Knuth洗牌。算法方面,每个人都应该熟悉Knuth,他是《计算机编程的艺术》一书的作者。和算法理论的创始人。他发明了用于我们现在正在使用的各种算法的复杂性分析的符号。等概率:有些人也称等概率混洗算法。实际上,发卡的过程与我们的图纸相同。大学概率论说,绘画是相等的概率。相同的随机播放算法以相等的概率选择每个元素。 。使用随机播放算法的思想,从5个数字1、2、3、4和5中,随机选择一个用于第一次随机提取的数字至4。选择此元素4的概率为1/5。第二次随机抽取为5该元素5被绘制的概率为1/4 * 4/5 = 1/5该元素2第三次被随机绘制的概率为1/3 * 3/4 * 4 / 5 = 1/5第4次随机选择元素1。选择1的概率为1/2 * 1/3 * 3/4 * 4/5 = 1/5。第五次随机选择元素3。的概率为1 * 1/2 * 1/3 * 3/4 * 4/5 = 1/5时间复杂度为O(n * n),空间复杂度为O(n)算法思想:引言在许可过程中,Knuth和Durstenfeld改进了基于Fisher等人的算法,与原始数组中的数字进行交互,从而节省了额外的O(n)空间。该算法的基本思想类似于Fisher。每次从未处理的数据中随机抽取一个数字,然后将该数字放置在数组的末尾,即,数组末尾的数字是已处理的数字。随机选择54张卡中的一张,按照剩余53张卡的顺序与第一张交换该卡,并继续随机选择其余53张卡中的一张与第二张卡交换,直到最后一张。时间复杂度为O(n),空间复杂度为O(1)。缺点是必须知道阵列长度n。代码:void  Knuth_Durstenfeld_Shuffle(vector& lt; int& gt;& amp; arr){& nbsp; for& nbsp;(int& nbsp; i = arr.size()-1; i& gt; = 1;-i){{& nbsp;& nbsp; srand((unsigned)time(NULL));& nbsp;& nbsp; swap(arr [rand()%(i + 1)],arr [i]);& nbsp;}}& nbsp;通过改组算法生成的雷区:将被排雷,使用改组算法加扰以生成(int& i = N * M-1; i& = 0; i-){  & nbsp;& nbsp; iX& nbsp; =& nbsp; i / M;& nbsp;& nbsp;& nbsp; // iX是X坐标;& nbsp; int& nbsp; iY& nbsp; =& nbsp; i%M; & nbsp;& nbsp; // iY是Y坐标nbsp;& nbsp;& nbsp;& nbsp;& nbsp; int& nbsp; randNumber& nbsp; =& nbsp;(int)(Math.random()*(i + 1)) );& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; int& nbsp; randX& nbsp; =& nbsp; randNumber / M;& nbsp;& nbsp ;& int& nbsp; randY& nbsp; =& nbsp; randNumber%M;& nbsp;& nbsp;& nbsp;& nbsp;& nbsp; swap(iX, iY,randX,randY);}生成的矿区地图点[寻找]是最大的支持。