1. 程式人生 > >Random Pick with Blacklist

Random Pick with Blacklist

Given a blacklist B containing unique integers from [0, N), write a function to return a uniform random integer from [0, N) which is NOT in B.

Optimize it such that it minimizes the call to system’s Math.random().

Note:

  1. 1 <= N <= 1000000000
  2. 0 <= B.length < min(100000, N)
  3. [0, N) does NOT include N. See 
    interval notation
    .

Example 1:

Input: 
["Solution","pick","pick","pick"]
[[1,[]],[],[],[]]
Output: [null,0,0,0]

Example 2:

Input: 
["Solution","pick","pick","pick"]
[[2,[]],[],[],[]]
Output: [null,1,1,1]

Example 3:

Input: 
["Solution","pick","pick","pick"]
[[3,[1]],[],[],[]]
Output: [null,0,0,2]

Example 4:

Input: 
["Solution","pick","pick","pick"]
[[4,[2]],[],[],[]]
Output: [null,1,3,1]

Explanation of Input Syntax:

The input is two lists: the subroutines called and their arguments. Solution's constructor has two arguments, N and the blacklist Bpick has no arguments. Arguments are always wrapped with a list, even if there aren't any.

題目理解:

返回0~N-1中的一個隨機數,但是不能是blacklist中有的數

解題思路:

如果blacklist的長度是len,那麼能夠選取的數就有N - len個。我們可以使用一個字典,使blacklist中的每一個數都對映到能夠選取到的最後幾個數,然後我們在0~N-len中找出一個隨機數,如果字典中存在這個數,那麼說明它存在於blacklist當中,就返回它對映到的數,如果不存在,那麼久返回這個數本身

程式碼如下:

class Solution {
	Map<Integer, Integer> map;
	int n;
    public Solution(int N, int[] blacklist) {
        map = new HashMap<Integer, Integer>();
        n = N - blacklist.length;
        Set<Integer> set = new HashSet<Integer>();
        for(int num : blacklist)
        	set.add(num);
        int right = N - 1;
        Arrays.sort(blacklist);
        for(int num : blacklist) {
        	while(set.contains(right))
        		right--;
        	map.put(num, right);
        	right--;
        }
    }
    
    public int pick() {
        Random rand = new Random();
        int r = rand.nextInt(n);
        return map.getOrDefault(r, r);
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(N, blacklist);
 * int param_1 = obj.pick();
 */