打乱数组-中等
难度:中等
题目描述:
打乱一个没有重复元素的数组。
示例:
// 以数字集合 1, 2 和 3 初始化数组。
int[] nums = {1,2,3};
Solution solution = new Solution(nums);
// 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。
solution.shuffle();
// 重设数组到它的初始状态[1,2,3]。
solution.reset();
// 随机返回数组[1,2,3]打乱后的结果。
solution.shuffle();
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
解题思路
洗牌算法能保证,对于生成的排列,每一个元素都能等概率的出现在每一个位置。
数组长度为n, 先从n个数据中,随机选取一个元素,与最后一个元素交换
每个元素被选中的概率是 1/n
从剩下长度的 n-1 元素中随便取一个,与倒数第二个元素交换,第一次没有被选中的概率为 n-1/n
第二次被选中的概率为 1/n-1 , 所以概率仍然是 (n-1)/n * 1/(n-1) = 1/n
所以每一个元素出现在每一个位置的概率,都是 1/n
var Solution = function (nums) {
this.arr = nums;
};
/**
* Resets the array to its original configuration and return it.
* @return {number[]}
*/
Solution.prototype.reset = function () {
return this.arr;
};
/**
* Returns a random shuffling of the array.
* @return {number[]}
*/
Solution.prototype.shuffle = function () {
let nums = [...this.arr];
let n = nums.length - 1;
while (n >= 0) {
let index = parseInt(Math.random() * (n + 1));
[nums[index], nums[n]] = [nums[n], nums[index]];
n--;
}
return nums;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26