LeetCode——384. 打乱数组(Java)

题目描述

题干:
给你一个整数数组 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]的排列返回的概率应该相同。
solution.reset();      // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3]
solution.shuffle();    // 随机返回数组 [1, 2, 3] 打乱后的结果。例如,返回 [1, 3, 2]

题解思路

设计一个打乱数组顺序的类,其中reset方法和初始化对象方法直接复制数组即可实现

而等概率的随机打乱数组方法肯定是要用到Random的方法,这里采用名叫洗牌算法的一种方法

每次将第一位与后面数字的其中一位交换顺序,然后依次用这种方式往后进行,每次确定新顺序的一位

正确代码

class RandomArraySolution {
    int[] nums;
    int[] original;

    public RandomArraySolution(int[] nums) {
        this.nums = nums;
        this.original = new int[nums.length];
        System.arraycopy(nums, 0, original, 0, nums.length);
    }
    
    public int[] reset() {
        System.arraycopy(original, 0, nums, 0, nums.length);
        return nums;
    }
    
    public int[] shuffle() {
        Random random = new Random();
        for (int i = 0; i < nums.length; i++) {
            int j = i + random.nextInt(nums.length - i);

            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
        return nums;
    }
}

总结

这里洗牌算法具体为什么能保证概率相同就不做证明了,可以去官方题解查看

倒是自己对random是否可以等概率存取还是挺好奇的,这里原地交换顺序也值得学习

如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,最高处见
posted @ 2021-11-22 10:09  21岁还不是架构师  阅读(125)  评论(0编辑  收藏  举报