难度:中等

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

    示例:

    1. // 以数字集合 1, 2 和 3 初始化数组。
    2. int[] nums = {1,2,3};
    3. Solution solution = new Solution(nums);
    4. // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。
    5. solution.shuffle();
    6. // 重设数组到它的初始状态[1,2,3]。
    7. solution.reset();
    8. // 随机返回数组[1,2,3]打乱后的结果。
    9. solution.shuffle();

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

    数组长度为n, 先从n个数据中,随机选取一个元素,与最后一个元素交换

    每个元素被选中的概率是 1/n

    从剩下长度的 n-1 元素中随便取一个,与倒数第二个元素交换,第一次没有被选中的概率为 n-1/n

    第二次被选中的概率为 1/n-1 , 所以概率仍然是 (n-1)/n * 1/(n-1) = 1/n

    所以每一个元素出现在每一个位置的概率,都是 1/n

    1. var Solution = function(nums) {
    2. this.arr = nums;
    3. };
    4. /**
    5. * Resets the array to its original configuration and return it.
    6. * @return {number[]}
    7. */
    8. Solution.prototype.reset = function() {
    9. return this.arr;
    10. };
    11. /**
    12. * Returns a random shuffling of the array.
    13. * @return {number[]}
    14. */
    15. Solution.prototype.shuffle = function() {
    16. let nums = [...this.arr];
    17. let n = nums.length - 1;
    18. while(n >= 0) {
    19. let index = parseInt(Math.random() * (n+1) );
    20. [nums[index], nums[n]] = [nums[n], nums[index]];
    21. n--;
    22. }
    23. return nums;
    24. };