Javascript 在Z时间内从大小为N的数组中获取Z个随机项?

Javascript 在Z时间内从大小为N的数组中获取Z个随机项?,javascript,algorithm,underscore.js,Javascript,Algorithm,Underscore.js,我有一个大小为N的数组,它可能以某种方式排序。我想在>0 | | 1; var deepBool=deep==true; var-roundCount=0; var指数、rnd、tmp; while(轮数0 | | 1; var deepBool=deep==true; var-roundCount=0; var指数、rnd、tmp; while(轮数

我有一个大小为N的数组,它可能以某种方式排序。我想在 我的理解是,如果我使用下划线的u.shuffle()洗牌数组,这将需要O(N)个时间。因此,洗牌然后抓取第一个Z项是不可能的

如果我在N之间生成Z个随机数,我想我会陷入非常糟糕的最坏情况。这是因为如果N是105,Z是100。。嗯,会有很多重叠,也许我会重新滚动Z几百次


我想知道这个问题是否有一个简单的解决方案?我没有看到任何下划线方法专门用于此任务。

我不认为我完全理解您的问题,但是如果您希望从数组中获取一个随机元素,并且该元素不会重复,因此滚动次数限制为少于元素,那么您可以尝试此方法

函数洗牌(obj、回合、深度){
变量长度=对象长度;
如果(长度<2){
返回;
}
var rounds32=轮数>>>0 | | 1;
var deepBool=deep==true;
var-roundCount=0;
var指数、rnd、tmp;
while(轮数<轮数32){
指数=长度;
while(索引){
if(Array.isArray(obj[index-1])){
洗牌(obj[i],第32轮,迪普布尔);
}
rnd=Math.floor(Math.random()*索引);
指数-=1;
tmp=obj[指数];
obj[索引]=obj[rnd];
obj[rnd]=tmp;
}
轮数+=1;
}
}
var数组=[];
对于(变量计数=0;计数<100;计数+=1){
array.push(计数);
}
洗牌(阵法);
var辊=10;

console.log(array.slice(0,rolls))我不认为我完全理解您的问题,但是如果您希望从数组中获取一个随机元素,并且它不会重复,因此您只能滚动少于元素的次数,那么您可以尝试此方法

函数洗牌(obj、回合、深度){
变量长度=对象长度;
如果(长度<2){
返回;
}
var rounds32=轮数>>>0 | | 1;
var deepBool=deep==true;
var-roundCount=0;
var指数、rnd、tmp;
while(轮数<轮数32){
指数=长度;
while(索引){
if(Array.isArray(obj[index-1])){
洗牌(obj[i],第32轮,迪普布尔);
}
rnd=Math.floor(Math.random()*索引);
指数-=1;
tmp=obj[指数];
obj[索引]=obj[rnd];
obj[rnd]=tmp;
}
轮数+=1;
}
}
var数组=[];
对于(变量计数=0;计数<100;计数+=1){
array.push(计数);
}
洗牌(阵法);
var辊=10;

console.log(array.slice(0,rolls))以下是一些需要考虑的算法:

A.洗牌

  • 洗牌阵;O(N)
  • 选择第一个Z项;O(Z)或更好
  • 总体复杂度:O(N)

    B.重新滚动的随机选择

  • 从0..N-1中选择一个随机数;O(1)
  • 如果之前已选择过号码,请转至步骤1
  • 记录拾取的编号;O(1)
  • 从给定索引处的数组中选择一项;O(1)
  • 如果拾取的项目少于Z个,请转至步骤1
  • 总体复杂性:


    对于Z,这里有一些算法需要考虑:

    A.洗牌

  • 洗牌阵;O(N)
  • 选择第一个Z项;O(Z)或更好
  • 总体复杂度:O(N)

    B.重新滚动的随机选择

  • 从0..N-1中选择一个随机数;O(1)
  • 如果之前已选择过号码,请转至步骤1
  • 记录拾取的编号;O(1)
  • 从给定索引处的数组中选择一项;O(1)
  • 如果拾取的项目少于Z个,请转至步骤1
  • 总体复杂性:


    对于Z,“function A(array, z) { return _.first(_.shuffle(array), z); }
    function B(array, z) {
      var pickedIndices = {};
      var result = [];
      while (result.length < z) {
        var randomIndex = Math.floor(Math.random() * array.length);
        if (!(randomIndex in pickedIndices)) {
          pickedIndices[randomIndex] = 1;
          result.push(array[randomIndex]);
        }
      }
      return result;
    }
    
    function C(array, z) {
      var result = [];
      array = array.slice(0);
      for (var i = 0; i < z; i++) {
        var randomIndex = Math.floor(Math.random() * array.length);
        result.push(array.splice(randomIndex, 1)[0]);
      }
      return result;
    }