题目
Shuffle a set of numbers without duplicates.
打乱一组不重复的数字。
示例
思路
思路1
最容易想到的思路,是第一次从n个数中随机选一个,第二次从n-1个中选,第三次从n-2个中选,第n次中选唯一的一个,一共是 n! 种结果。
于是选择用一个list来存储下标,每次随机选择一下标,将该下标对应的元素值赋给新数组,选择完成后,将选定下标从list中移除。n次循环后得到想要的结果。
思路2
可以考虑直接对数组元素进行交换。我们希望达成的效果是,任意元素到任意位置的概率是相同的。
要实现任意位置,可以使用一次遍历,即n个循环。
要实现任意元素,可以每次循环随机选择一下标的元素。
每次交换指定下标的元素与当前位置的元素,即可得到结果。
题解
题解1
class Solution {
public int[] initNums;
public int[] shuffledNums;
public int len;
public LinkedList <Integer> list;
public Solution(int[] nums) {
initNums = nums;
shuffledNums = Arrays.copyOf(nums, nums.length);
len = nums.length;
list = new LinkedList<>();
for(int i=0;i<len;i++){
list.add(i);
}
}
/** Resets the array to its original configuration and return it. */
public int[] reset() {
return initNums;
}
/** Returns a random shuffling of the array. */
public int[] shuffle() {
Random random = new Random();
LinkedList <Integer> temp = new LinkedList<>(list);
int index;
for(int i=len-1;i>=0;i--){
index = random.nextInt(i+1);
shuffledNums[i] = initNums[temp.get(index)];
temp.remove(index);
}
return shuffledNums;
}
}
/**
* 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();
*/
题解2
class Solution {
public int[] initNums;
public int[] shuffledNums;
public Solution(int[] nums) {
initNums = nums;
shuffledNums = Arrays.copyOf(nums,nums.length);
}
/** Resets the array to its original configuration and return it. */
public int[] reset() {
return initNums;
}
/** Returns a random shuffling of the array. */
public int[] shuffle() {
Random random = new Random();
for(int i=0;i<shuffledNums.length;i++){
swap(shuffledNums,i,random.nextInt(shuffledNums.length));
}
return shuffledNums;
}
public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
/**
* 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();
*/
反思
复杂度分析
思路1
时间复杂度:O(n)
空间复杂度:O(n)
思路2
时间复杂度:O(n)
空间复杂度:O(n)
两种方法相差无几
扩展
该题所用到的算法是一种洗牌算法。
关于几种洗牌算法以及蓄水池抽样算法的实现,可以移步☞洗牌算法。