710. 黑名单中的随机数
给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数。
对它进行优化使其尽量少调用系统方法 Math.random() 。
提示:
1 <= N <= 1000000000
0 <= B.length < min(100000, N)
[0, N) 不包含 N,详细参见 interval notation 。
示例 1:
输入:
["Solution","pick","pick","pick"]
[[1,[]],[],[],[]]
输出: [null,0,0,0]
示例 2:
输入:
["Solution","pick","pick","pick"]
[[2,[]],[],[],[]]
输出: [null,1,1,1]
示例 3:
输入:
["Solution","pick","pick","pick"]
[[3,[1]],[],[],[]]
Output: [null,0,0,2]
示例 4:
输入:
["Solution","pick","pick","pick"]
[[4,[2]],[],[],[]]
输出: [null,1,3,1]
解题思路
利用逻辑上的紧凑数组实现
N个数中,加入有m个黑名单。则将非黑名单的数字逻辑上存放在前N-m中。这样可以通过随机索引保证随机
如果黑名单在前半部分,则与后半部分的值交换---此时用map存index到val的映射。其他正常的index=val。则不用再次存储
ps:代码看了好几遍没问题,但是运行不过
试运行结果正确,提交时又不通过。同样的用例。之后再看
java代码
class Solution {
public static int sz;
public static Map<Integer,Integer> map=new HashMap<>();
public Solution(int N, int[] blacklist) {
for(int b:blacklist){
map.put(b,-1);
}
sz=N-blacklist.length;
int last=N-1;
for(int b:blacklist){
if(b>=sz){
continue;
}
//找到未在前方的最后一个正常数
while(map.containsKey(last)){
last--;
}
//交换
map.put(b,last);
//舍弃交换后的黑名单
last--;
}
}
public int pick() {
int index=(int)(Math.random()*sz);
//交换过的数在map中,其他的就等于index
if(map.containsKey(index)){
return map.get(index);
}
return index;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(N, blacklist);
* int param_1 = obj.pick();
*/
京公网安备 11010502036488号