1. 问题

给定一个黑名单,包含[0, N)的一些数,从[0, N)之间的非黑名单数中随机采样一个值。

2. 思路

字典映射

(1)计算黑名单数的长度,记作B,因为已经排除掉了B个元素,所以最后是从N-B个数中采样。

(2)可以维护一个字典,表示从[0, N-B)到[0, N)之间的映射。

(3)这样就可以每次采样从[0, N-B)之间取,采样后将值映射回[0, N)。

(4)然而这么做爆内存了(MemoryError),因为N的最大长度为10亿,B的最大长度为10万,N-B特别大。

时间复杂度:O(N-B),空间复杂度:O(N-B),B表示blacklist的长度

(方法二)字典映射

(1)实际上我们不需要维护[0, N-B)中每个数的映射,我们只需要考虑[0, N-B)中的blacklist元素,因为只有这些元素才发生冲突。

(2)考虑换一种映射方法,因为是从[0, N-B)中采样,我们只需要考虑把[0, N-B)中的blacklist元素映射到[N-B, N)即可。

(3)而[N-B, N)中的blacklist元素是不需要(也不能)被映射的。我们只需要考虑那些[N-B, N)中不在blacklist中的元素,保证这些元素被映射就好了。

(4)所以我们只需要遍历[N-B, N)里面的B个元素,如果元素不在blacklist中,就建立一个映射,让blacklist中的元素(按顺序递增)指向它。

(5)这里判断元素是否在blacklist时,使用set效率会更高(一开始使用的list导致了超时)。映射时还是使用list的blacklist,因为要按顺序来映射。

时间复杂度:O(B * logB),空间复杂度:O(B),B表示blacklist的长度

3. 代码

字典映射

class Solution(object):
def __init__(self, N, blacklist):
"""
:type N: int
:type blacklist: List[int]
"""
B = len(blacklist)
dic = {}
offset = 0
for i in range(N-B):
if(i+offset not in blacklist):
dic[i] = i + offset
else:
offset += 1
dic[i] = i + offset
self.dic = dic
self.N = N-B def pick(self):
"""
:rtype: int
"""
i = random.randint(0,self.N-1)
return self.dic[i]

(方法二)字典映射

class Solution(object):
def __init__(self, N, blacklist):
blacklist.sort()
blacklist_set = set(blacklist)
self.dic = {}
self.M = N - len(blacklist)
j = 0
for i in range(self.M, N):
if i not in blacklist_set:
self.dic[blacklist[j]] = i
j += 1 def pick(self):
i = random.randint(0,self.M - 1)
return self.dic[i] if i in self.dic else i

710 Random Pick with Blacklist的更多相关文章

  1. 710. Random Pick with Blacklist - LeetCode

    Question 710. Random Pick with Blacklist Solution 题目大意:给一个N,表示一个范围[0,N),给一个黑名单列表blacklist,其中blacklis ...

  2. [LeetCode] Random Pick with Blacklist 带黑名单的随机选取

    Given a blacklist B containing unique integers from [0, N), write a function to return a uniform ran ...

  3. [Swift]LeetCode710. 黑名单中的随机数 | Random Pick with Blacklist

    Given a blacklist B containing unique integers from [0, N), write a function to return a uniform ran ...

  4. [LeetCode] Random Pick with Weight 根据权重随机取点

    Given an array w of positive integers, where w[i] describes the weight of index i, write a function  ...

  5. LeetCode 528. Random Pick with Weight

    原题链接在这里:https://leetcode.com/problems/random-pick-with-weight/ 题目: Given an array w of positive inte ...

  6. 398. Random Pick Index - LeetCode

    Question 398. Random Pick Index Solution 思路:重点是如果数据中有多个数target相等,要从这些数中随机取一个,根据例题 假设输入是: int[] nums ...

  7. [LeetCode] Random Pick Index 随机拾取序列

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  8. Random Pick Index

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  9. Leetcode: Random Pick Index

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

随机推荐

  1. 神奇的thrust::device_vector与nvcc编译选项

    在C++的GPU库thrust中,有两种vector thrust::device_vector<int> D; //GPU使用的内存中的向量 thrust::host_vector< ...

  2. vue---设置缩进为4个空格

    在使用vue-cli的时候,我们发现,默认编辑的时候,使用的缩进都是2个空格,即使是是编辑器设置了4个空格,在编译的时候,还是以2个空格进行缩进,那么如果将vue设置为4个空格呢? 具体方法在根目录找 ...

  3. Shell sleep指定延迟时间

    可以给时间,让上一条命令执行完毕后,并且退出 sleep 1 睡眠1秒sleep 1s 睡眠1秒sleep 1m 睡眠1分sleep 1h 睡眠1小时

  4. [译] 深入理解 JavaScript 事件循环(二)— task and microtask

    引言 microtask 这一名词是 JS 中比较新的概念,几乎所有人都是在学习 ES6 的 Promise 时才接触这一新概念,我也不例外.当我刚开始学习 Promise 的时候,对其中回调函数的执 ...

  5. 计蒜客 30996 - Lpl and Energy-saving Lamps - [线段树][2018ICPC南京网络预赛G题]

    题目链接:https://nanti.jisuanke.com/t/30996 During tea-drinking, princess, amongst other things, asked w ...

  6. flask数据库操作

    Python 数据库框架 大多数的数据库引擎都有对应的 Python 包,包括开源包和商业包.Flask 并不限制你使用何种类型的数据库包,因此可以根据自己的喜好选择使用 MySQL.Postgres ...

  7. pandas2

    1.Series创建的方法统一为pd.Series(data,index=)(1,2,3)Series可以通过三种形式创建:python的dict.numpy当中的ndarray(numpy中的基本数 ...

  8. Rikka with Parenthesis II---hdu5831(括号匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5831 给你一个只包含‘(’‘)’的字符串,然后让我们交换两个字符一次,问是否能得到一个合法的匹配:必须 ...

  9. 洛谷P2634 聪聪可可 [国家集训队] 点分治/dp

    正解:点分治/dp 解题报告: 传送门! 这题有两个做法,都是我不擅长的就都说下好了QAQ 首先这题一看到就会想到点分治? 也确实可以用点分治,那就直接用点分治鸭 每次求出到当前根距离余数为0,1,2 ...

  10. Servlet----------ServletContext (重要)

    1.ServletContext的概述 一个项目只有一个ServletContext对象!application 我们可以在N多个Servlet中获取这个唯一的对象,使用它来给多个Servlet传递数 ...