随机算法之30万员工抽取10万员工(洗牌算法)

算法方面不是我的强项,所以遇到这个问题,记录一下解决方法;

最开始的时候,做法是从random中来随机选取一个,然后再判断已有列表中是否存在,

然后以此重复,看到这里,会算法的同学肯定会说这明显不行;就好比多少人中生日为一天的概率大于50%;

所以然后查找了一些资料,看到了洗牌算法;包括多种变种吧。

这里说一下我参考的解决办法;

比如有30万个元素的列表,那么第一次随机选择一个;记录位置是x;

然后把元素的最后一个位置元素存入位置x,然后把最后位置的元素删除;

(这里在交换的时候,需要判断这个元素原本是不是最后一个元素);

然后再在剩下的元素中随机选择一个,这样就不会重复了;

交换最后一个元素,可以减少列表整体偏移带来的性能影响;

大家可以试试;

时间: 2024-10-16 22:31:36

随机算法之30万员工抽取10万员工(洗牌算法)的相关文章

洗牌算法Fisher-Yates以及C语言随机数的产生

前些天在蘑菇街的面试中碰到一道洗牌的算法题,拿出来和大家分享一下! 原题是:54张有序的牌,如何无序的发给3个人? 这个题是运用经典的洗牌算法完成.首先介绍一种经典的洗牌算法--Fisher-Yates.现在大家在网上看到,大多是Fisher-Yates算法的变形.将本来O(n2),简化到了O(n).代码如下: #include<stdio.h> #include <stdlib.h> void func(char *, int); void main() { char a[7]

转:浅谈洗牌算法(面试题)

很多人都有耳闻过洗牌算法,时常会在面试中碰到,我们下面来定义一下这个问题. 所谓洗牌算法,就是给你一个1到n的序列,让你随机打乱,保证每个数出现在任意一个位置的概率相同,也就是说在n!个的排列中,每一个排列出现的概率相同. 最朴素的做法 对于这个问题我们从最朴素的解法谈起.每次随机选出一个没有被选过的数放到一个队列中,如果随机出来的数已经被选过,那么继续随机直到遇到一个没有被选过的数放入到队列中:重复这样子操作直到所有的数都被选择出来. 我们看看这样子作为什么是对的.首先选第一个数的时候有n个数

随机洗牌算法

随机洗牌算法: 时间和空间复杂度都为O(n). 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 54; 6 7 void random_shuffle(vector<int> &a) 8 { 9 srand(int(time(0))); 10 int aSize = a.size(); 11 for(int i = 1; i != aSize; ++i) { 12 int j

随机洗牌算法Knuth Shuffle和错排公式

Knuth随机洗牌算法:譬如现在有54张牌,如何洗牌才能保证随机性.可以这么考虑,从最末尾一张牌开始洗,对于每一张牌,编号在该牌前面的牌中任意一张选一张和当前牌进行交换,直至洗到第一张牌为止.参考代码如下: void knuth() { for (int i = 54; i > 1; i--) { int id = rand() % (i - 1) + 1; swap(a[i], a[id]); } } 由上述方法可知,每一张牌经过洗牌之后一定不会出现在原来位置,那么一共会有多少情况呢,这其实就

Javascript 洗牌算法,打乱数组,随机获取元素

//利用洗牌算法Array.prototype.shuffle=function(){ var i,t,m=this.length; while(m){ i=Math.floor(Math.random()*m--); t=this[m]; this[m]=this[i]; this[i]=t; } return this;} var arr=[1,2,3,4,5];console.log(arr.shuffle());console.log(arr.slice(0,2));

扑克牌的完美洗牌算法

思路: 递归思想.我们有n张牌,不妨先假设有一个洗牌函数shuffle(....),能完美的洗出n-1张牌 .拿第n张牌来打乱前面n-1的洗牌顺序,从而得到n张牌的最终结果. 代码如下: 1 #include <iostream> 2 #include <cstdlib> 3 using namespace std; 4 5 //随机指定区域内的数 6 int MyRand(int low, int high) 7 { 8 return low + rand() % (high -

JS洗牌算法

洗牌算法 以请将1~10共10个数字的数组随机打乱为列子,目前我知道的有两种方法,一种sort()方法和push()方法. 一.sort方法: var arr=[1,2,3,4,5,6,7,8,9]; function Upset(a,b) { //用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1   return Math.random()>.5 ? -1 : 1;  //简化上面的方法 // return 0.5 - Math.random();  } arr

【转】完美洗牌算法

转自:https://yq.aliyun.com/articles/3575 题目 有个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后{a1,b1,a2,b2,….,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法. 来源 2013年UC的校招笔试题 思路一 第①步.确定b1的位置,即让b1跟它前面的a2,a3,a4交换: a1,b1,a2,a3,a4,b2,b3,b4 第②步.接着确定b2的位置,即让b2跟它前面的a3,a4交换: a

算法之洗牌算法

洗牌算法是我们常见的随机问题,在玩游戏.随机排序时经常会碰到,一个最常用的地方就是组卷.它可以抽象成这样:M以内的所有自然数的随机顺序数组. package com.math; import java.util.Random; /** * @author summer * */ public class Shuffle { static final int[] a = new int[54]; static Random rnd = new Random(); static{ for(int i