题目
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果
代码
class Solution {
int[] backup;
int n;
Random random = new Random();
public Solution(int[] nums) {
backup=nums;
n=nums.length;
}
public int[] reset() {
return backup;
}
public int[] shuffle() {
int[] nums=backup.clone();
for (int i = 0; i <n; i++) {//选取一个i之后随机下标的值与i的值交换
int p=i+random.nextInt(n-i);
swap(nums,i,p);
}
return nums;
}
private void swap(int[] arr,int i, int j){
int c = arr[i];
arr[i] = arr[j];
arr[j] = c;
}
}
要点
-
Knuth 洗牌算法:我们从前往后尝试填充 [0, n - 1] 该填入什么数时,通过随机当前下标与(剩余的)哪个下标进行值交换来实现。
-
对于下标 xx 而言,我们从 [x, n - 1] 中随机出一个位置与 xx 进行值交换,当所有位置都进行这样的处理后,我们便得到了一个公平的洗牌方案。