【LeetCode】打乱数组Java题解

322 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目描述

给你一个整数数组 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]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shuffle-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

  • 今天的算法每日一题是设计类题目,设计一个数组的 shuffle() 函数, shuffle() 在我们的数据处理工程中,应用广泛。
  • 题目要求设计两个函数, shuffle() 和 reset()。对于数组来说,就是交换元素的位置,我们一般通过索引来交换元素的位置,实现swap函数,时间复杂度是O(1)。
  • 如何确定交换的位置呢?采用 random 函数获取随机交换的位置。实现代码如下:

通过代码

class Solution {
    private int[] arr;
    private int[] original;

    Random rand = new Random();

    private int randRange(int min, int max) {
        return rand.nextInt(max - min) + min;
    }

    private void swap(int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public Solution(int[] nums) {
        arr = nums;
        original = nums.clone();
    }
    
    public int[] reset() {
        arr = original;
        original = original.clone();
        return original;
    }
    
    public int[] shuffle() {
        for (int i = 0; i < arr.length; i++) {
            swap(i, randRange(i, arr.length));
        }
        return arr;
    }
}


/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int[] param_1 = obj.reset();
 * int[] param_2 = obj.shuffle();
 */

image.png

总结

  • 设计类题目考察的是思维的清晰,以及代码的实现能力,算法中,设计类题目相对较少,我们应该在平时使用函数的同时,了解原理,拓展和完善自己的思维。
  • 坚持算法每日一题,加油!