384. Shuffle an Array

来源:互联网 发布:数据库设计那些事儿 编辑:程序博客网 时间:2024/05/23 14:16

Shuffle a set of numbers without duplicates.

Example:

// Init an array with set 1, 2, and 3.int[] nums = {1,2,3};Solution solution = new Solution(nums);// Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned.solution.shuffle();// Resets the array back to its original configuration [1,2,3].solution.reset();// Returns the random shuffling of array [1,2,3].solution.shuffle();


没有重复的元素,那么就可以把所有的元素塞入HashSet,再一个个地取出来,每次根据剩余元素的个数生成随机数,生成的随机数作为Iterator前进的步数,把对应的元素取出来并从HashSet中删除直到HashSet空为止。


public class Solution {HashSet<Integer> hashset;int[] numscpy;Random rand;    public Solution(int[] nums) {        hashset=new HashSet<>();        rand=new Random();        numscpy=new int[nums.length];        System.arraycopy(nums, 0, numscpy, 0, nums.length);        for(int num :nums)        hashset.add(num);    }        /** Resets the array to its original configuration and return it. */    public int[] reset() {        return numscpy;    }        /** Returns a random shuffling of the array. */    public int[] shuffle() {    HashSet<Integer> tset=new HashSet<>(hashset);        int size=tset.size();        int[] retarr=new int[size];        for(int i=size,j=0;i>=1;i--,j++)        {        int randnum=rand.nextInt(i);        Iterator<Integer> it=tset.iterator();        int n=it.next();        for(int k=0;k<randnum;k++)        n=it.next();                retarr[j]=n;        it.remove();        }        return retarr;    }}/** * 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(); */</span>



------------------------------------------------------------------------------------------------------------

其他方法,直接置换,使得原array的每个index上的元素以1/array.length()的概率保留,摘自

https://discuss.leetcode.com/topic/53978/first-accepted-solution-java/11


Proof: Suppose this algorithm works, i.e. for each position j (starting from 0), the probability of any number in the range[0,j] to be at position j is 1/(1+j).

Let's look at int i = random.nextInt(j + 1):
(1) If i == j, nums[j] does not need to change its position, which has probability 1/(1+j).
(2) if i !=j, nums[j] needs to be swapped with nums[i]. The probability of any number x in the range [0,j-1] to be at position j = nums[j] changes its position * x is at position i
= (1-1/(1+j)) * (1/j) = 1/(1+j)

Each number has equal probability to be at any position


 It looks like we can give a little proof of correctness here. For the 0th element, the probability for that it stays at index 0 position, is 1/1 * (2-1)/2 * (3-1)/3 * ... (n-1)/n = 1/n. The probability for that it will stay at index 1 is 1/2 * (3-1)/3 * ... = 1/n. This means for the 0th element, it has 1/n probability to be placed into any position.

Once we know that 0th element will stay at index x, for simplicity, we know that 0th element will stay at index 0, then what is the probability of 1st element to stay 1st position? it is 1/1 * 1/2 * ... (n-2)/(n-1) = 1/(n-1). This implies that for the 1st element, it has 1/(n-1) probability to be placed into any un-occupied position.

Not quite sure whether we can do the above analysis by fixing 0th element's position.

Then one complete sequence will have probability of 1/(n!) to be chosen, which fits the requirement.


public class Solution {    private int[] nums;    private Random random;    public Solution(int[] nums) {        this.nums = nums;        random = new Random();    }        /** Resets the array to its original configuration and return it. */    public int[] reset() {        return nums;    }        /** Returns a random shuffling of the array. */    public int[] shuffle() {        if(nums == null) return null;        int[] a = nums.clone();        for(int j = 1; j < a.length; j++) {            int i = random.nextInt(j + 1);            swap(a, i, j);        }        return a;    }        private void swap(int[] a, int i, int j) {        int t = a[i];        a[i] = a[j];        a[j] = t;    }}

0 0
原创粉丝点击