384. 打乱数组

108 阅读1分钟

384. 打乱数组

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

  • 给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。

  • 实现 Solution class:

    • Solution(int[] nums) 使用整数数组 nums 初始化对象
    • int[] reset() 重设数组到它的初始状态并返回
    • int[] shuffle() 返回数组随机打乱后的结果  
示例:

输入
["Solution", "shuffle", "reset", "shuffle"]
[[[1, 2, 3]], [], [], []]
输出
[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]

解释
Solution solution = new Solution([1, 2, 3]);
solution.shuffle();    // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。例如,返回 [3, 1, 2]
solution.reset();      // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3]
solution.shuffle();    // 随机返回数组 [1, 2, 3] 打乱后的结果。例如,返回 [1, 3, 2]


提示:

1 <= nums.length <= 200
-106 <= nums[i] <= 106
nums 中的所有元素都是 唯一的
最多可以调用 5 * 104 次 reset 和 shuffle

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/sh…

思路:洗牌算法

  • 原本是可以将再改变第i元素的时候,进行与最后一个元素交换的
    • 但是我们可以不采用移除的办法,二十采用每次原地更换

    • 更换的前提是,我们需要在第i次循环的时候在i~n中随机取下标

    • 然后将第i和j的下标元素进行互换

  • arraycopy是将一个数组的指定个数元素复制到另一个数组中
class Solution {
    int[] nums;
    int[] orign;
    public Solution(int[] nums) {
        this.nums = nums;
        this.orign = new int[nums.length];
        System.arraycopy(nums,0,orign,0,nums.length);
    }
    
    public int[] reset() {
        System.arraycopy(orign,0,nums,0,nums.length);
        return nums;
    }
    
    public int[] shuffle() {
        Random random = new Random();
        for (int i = 0; i < nums.length; i++) {
            // i~n之间随机也数
            int j = i + random.nextInt(nums.length - i);
            int t = nums[i];
            nums[i] = nums[j];
            nums[j] = t;
        }

        return nums;
    }
}