面试题反思:随机打乱数组顺序(考察随机数的使用)

引言

前段时间面试碰到一道题,题目主要就是随机打乱一个数组的顺序。乍一听我觉得挺简单的,但是到写代码的时候却有种“无从下手”的感觉,原因在于自己其实之前并没有使用过(也没有仔细思考过)“随机性”

产生指定范围的随机数

Math.random()返回一个随机数,均匀分布在[0,1)范围。用这个方法我们可以在任意范围产生随机数。
比如

  • Math.random()*10均匀分布在[0,10)范围的有理数
  • Math.floor(Math.random()*10)均匀分布在[0,9]范围的整数(得到0~9这10个整数的概率相同)。
  • Math.floor(Math.random()*10)+55:均匀分布在[55,64]范围的整数(得到这10个整数的概率相同)。

更一般化的,产生指定范围的随机有理数方法:

// 产生一个[min,max)范围的随机有理数
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

产生指定范围的随机整数的方法:

// 产生一个[min,max]范围的随机整数,注意这个范围包含max
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

上面这个方法中的+ 1是一个很容易遗漏的地方,考虑一下为什么Math.floor(Math.random()*10)最大只能产生9。

用随机数打乱数组

一个简洁的办法是,利用sort:

function shuffle(array) {
    array.sort(function() {
        return 0.5 - Math.random();
    });
}

但是这种方法并不能做到真正的“均匀打乱”,可以看看参考资料3中的知乎讨论。
这位答主结合生动的图片解释了更好的均匀打乱算法:Fisher–Yates shuffle。

function shuffle(array) {
    var m = array.length,
        t, i;
    while (m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
    }
    return array;
}

这里就不盗人家的图了,读者可以点击链接查看。
这个简洁的算法不难理解,主要的步骤是i = Math.floor(Math.random() * m--),这个语句先获取一个[0,m-1]范围的随机下标赋值给i,然后m=m-1

参考资料

  1. https://stackoverflow.com/que...
  2. https://stackoverflow.com/que...
  3. https://www.zhihu.com/questio...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值