打乱数组-中等

难度:中等

题目描述:
打乱一个没有重复元素的数组。

示例:

// 以数字集合 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



解题思路
洗牌算法能保证,对于生成的排列,每一个元素都能等概率的出现在每一个位置。

数组长度为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
最后更新时间: 6/9/2020, 8:21:32 PM