题目描述
题干:
给你一个整数数组 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是否可以等概率存取还是挺好奇的,这里原地交换顺序也值得学习
如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,最高处见