如何生成0-9不重复随机数?解决Math.random()重复问题
解决0-9不重复随机数生成的问题
嘿,我明白你现在的困扰——用Math.floor(Math.random() * 10)生成0-9的随机数时总是出现重复,而且当前的循环逻辑还在反复生成重复值,想找到更靠谱的方法生成无重复的序列对吧?
最优方案:Fisher-Yates洗牌算法
其实最高效也最避免重复循环问题的方法是洗牌法。我们先创建一个包含0到9的有序数组,然后通过打乱数组的方式得到随机无重复序列,完全不用反复生成随机数再检查重复。
具体实现代码如下:
function getUniqueRandomNumbers() { // 初始化包含0-9的有序数组 const nums = Array.from({ length: 10 }, (_, index) => index); // Fisher-Yates洗牌过程 for (let i = nums.length - 1; i > 0; i--) { // 生成0到当前索引的随机位置 const randomIndex = Math.floor(Math.random() * (i + 1)); // 交换当前元素和随机位置的元素 [nums[i], nums[randomIndex]] = [nums[randomIndex], nums[i]]; } return nums; } // 调用示例 console.log(getUniqueRandomNumbers().join(', '));
这个方法的优势在于:
- 时间复杂度是O(n),效率极高,不会出现反复循环生成重复值的情况
- 直接通过打乱有序数组得到结果,逻辑简单且可靠,刚好能满足你要10个不重复数的需求(因为0-9刚好10个数,洗牌后就是全量无重复的随机序列)
备选方案:检查重复后添加
如果你更倾向于保留“生成随机数-检查是否重复”的逻辑,也可以这样写,虽然效率略低,但对于10个数的场景完全够用:
function getUniqueRandomNumbersAlternative() { const result = []; while (result.length < 10) { const randomNum = Math.floor(Math.random() * 10); // 如果当前数不在结果数组里,就添加进去 if (!result.includes(randomNum)) { result.push(randomNum); } } return result; }
不过要注意,当结果数组快填满的时候(比如已经有9个数),下一次生成正确数字的概率只有1/10,可能会多循环几次,但因为总数只有10个,所以绝对不会出现死循环。
总的来说,更推荐用Fisher-Yates洗牌法,它从根源上避免了重复生成和循环检查的问题,是处理这类“全量无重复随机序列”需求的标准解法。
内容的提问来源于stack exchange,提问作者Piotr Mirosz
相关产品推荐
相关产品推荐

