Javascript 洗牌数组编码挑战。理解一个部分有困难

Javascript 洗牌数组编码挑战。理解一个部分有困难,javascript,Javascript,问题: 洗牌一组没有重复的数字 Example: // Init an array with set 1, 2, and 3. int[] nums = {1,2,3}; Solution solution = new Solution(nums); // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned. solutio

问题: 洗牌一组没有重复的数字

Example:

// Init an array with set 1, 2, and 3.
int[] nums = {1,2,3};
Solution solution = new Solution(nums);

// Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned.
solution.shuffle();

// Resets the array back to its original configuration [1,2,3].
solution.reset();

// Returns the random shuffling of array [1,2,3].
solution.shuffle();
答复:

 var Solution = function(nums) {

// hold nums in Solution

   this.nums = nums;
};

Solution.prototype.reset = function() {
   return this.nums;
};

Solution.prototype.shuffle = function() {

// create a copy of this.nums, shuffle it, and return it0

const shuffled = this.nums.slice();
const n = shuffled.length;
const swap = (arr, i, j) => {
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

// swap elements with random elements
for (let i = 0; i < n; i++) 
    swap(shuffled, i, Math.floor(Math.random() * n));

return shuffled;
};
var解决方案=函数(nums){
//在溶液中保留NUM
this.nums=nums;
};
Solution.prototype.reset=函数(){
返回此.nums;
};
Solution.prototype.shuffle=函数(){
//创建this.nums的副本,将其洗牌,然后返回0
const shuffled=this.nums.slice();
常数n=无序排列的长度;
常量交换=(arr,i,j)=>{
设tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
//用随机元素交换元素
for(设i=0;i
我的问题: 使用Math.floor(Math.random()*n)可以从数组的长度中获得一个随机索引。我不明白,这个代码不能复制吗?如果长度是3。公式不能得到2的索引和另一个2的索引,从而产生重复索引。谁能澄清我的误解吗。谢谢Math.random是否会自动提取已使用的索引?

是的,
Math.floor(Math.random()*n)
表达式可以多次计算到相同的数字,但这没关系,因为该随机数正在
交换中使用,它将索引
i
处的数字与所选随机索引处的数字进行切换

如果随机索引取自原始数组并添加到要返回的数组中,例如

const randIndex = Math.floor(Math.random() * n);
arrToBeReturned.push(arr[randIndex]);
你是对的,但算法不是这样做的。想象一下,随机排序一组
[1,2,3]

循环的第一次迭代:
i
为0,选择的随机索引为2。互换标记0和2:

[3, 2, 1]
第二次迭代:
i
为1,选择的随机索引为2。互换指标1和2:

[3, 1, 2]
第三次迭代:
i
为2,选择的随机索引为2。互换指标2和2:

[3, 1, 2]
使用此代码,每个索引至少与另一个索引随机交换一次,确保最后数组是随机的,没有偏差(假设
Math.random
是可信的)。

Math.floor(Math.random()*n)是的,它可以估值为相同的指数,但这里您使用数字来交换元素,所以这是可以的

Math.random是否自动提取已使用的索引

不,不需要。您需要跟踪以前生成的值

你可以做的是让一个变量a
对象
映射
来跟踪之前的添加索引,如果随机生成的索引尚未包含在该变量中,则将其添加到最终输出,否则再次生成新索引

但在这种情况下,它是不需要的