题目:384. 打乱数组 给你一个整数数组 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
-10^6 <= nums[i] <= 10^6
nums
中的所有元素都是 唯一的
最多可以调用 5 * 10^4
次 reset
和 shuffle
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/shuffle-an-array 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
暴力
Fisher-Yates洗牌算法
解题代码 暴力 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 27 28 29 30 31 32 33 34 35 class Solution { public int [] nums; public Solution (int [] nums) { this .nums = nums; } public int [] reset() { return nums; } public int [] shuffle() { int [] res = new int [nums.length]; HashSet<Integer> hashSet = new HashSet <>(); Random random = new Random (); for (int i = 0 ; i < res.length; i++){ int rand = random.nextInt(res.length); if (hashSet.add(rand)){ res[i] = nums[rand]; }else { i--; } } return res; } }
官方解题代码 暴力 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 27 28 29 30 31 32 33 34 35 36 37 class Solution { private int [] array; private int [] original; private Random rand = new Random (); private List<Integer> getArrayCopy () { List<Integer> asList = new ArrayList <Integer>(); for (int i = 0 ; i < array.length; i++) { asList.add(array[i]); } return asList; } public Solution (int [] nums) { array = nums; original = nums.clone(); } public int [] reset() { array = original; original = original.clone(); return array; } public int [] shuffle() { List<Integer> aux = getArrayCopy(); for (int i = 0 ; i < array.length; i++) { int removeIdx = rand.nextInt(aux.size()); array[i] = aux.get(removeIdx); aux.remove(removeIdx); } return array; } }
Fisher-Yates洗牌算法 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 27 28 29 30 31 32 33 34 class Solution { private int [] array; private int [] original; Random rand = new Random (); private int randRange (int min, int max) { return rand.nextInt(max - min) + min; } private void swapAt (int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } public Solution (int [] nums) { array = nums; original = nums.clone(); } public int [] reset() { array = original; original = original.clone(); return original; } public int [] shuffle() { for (int i = 0 ; i < array.length; i++) { swapAt(i, randRange(i, array.length)); } return array; } }