Random Pick with Blacklist
阿新 • • 發佈:2018-12-10
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 <= N <= 1000000000
0 <= B.length < min(100000, N)
[0, N)
does NOT include N. See
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 B
. pick
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();
*/