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;
}
}