题目如下
【leetcode】710. Random Pick with Blacklist 解题报告

给定N,和一个黑名单数组,要求每次从[0,N)中选出一个随机数,这个随机数不能存在于黑名单中
思路:
最终结果中随机数的个数肯定是N-len(blacklist),所以我们要一是要选择出最后的随机值,一个是要将黑名单的中的值映射到白名单中
结果中的随机数的个数为N-len(blacklist),那么我们肯定先取数组[0,N]的前N-len(blacklist)个元素,但是这前N-len(blacklist)如果有黑名单中的元素怎么办呢。我们用一个指针从后往前扫描这个数组,如果后面的值不在黑名单中而前面的值在黑名单中,则用后面的值替换前面的即可。
在上述操作后,我们就将random的范围从N缩小到了N- len(blacklist)大小的范围中,用一个map存起来,键为1~N-len(blacklist),值为白名单中的数
第一次提交代码如下

class Solution:
   def __init__(self, N, blacklist):
        """
        :type N: int
        :type blacklist: List[int]
        """
        self.map = {}
        for i in blacklist:
            self.map[i] = 1
        self.M = N - len(blacklist)
        for i in blacklist:
            if i < self.M:
                N = N-1
                while N in self.map:
                    N -= 1
                self.map[i] = N
        for i in range(self.M):
            if i not in self.map:
                self.map[i] = i
    def pick(self):
        """
        :rtype: int
        """
        import  random
        return self.map[random.randint(0,self.M-1)]

过了 47个例子,然后报了如下的超出内存的错误

【leetcode】710. Random Pick with Blacklist 解题报告
还是第一次遇到超出内存的error
review了一下代码,发现了可以优化的地方

 for i in range(self.M):
            if i not in self.map:
                self.map[i] = i

这段代码其实是没必要的,没必要将所有白名单的映射都记录下来,只要记录下来那些在0~N-len(blacklist)中需要重新映射的数即可,因为大部分数字都是不变的,比如随机到1它范围的就是1,随机到黑名单中数时才需要查表
AC代码:

class Solution:

    def __init__(self, N, blacklist):
        """
        :type N: int
        :type blacklist: List[int]
        """
        self.map = {}

        for i in blacklist:
            self.map[i] = 1
        self.M = N - len(blacklist)
        for i in blacklist:
            if i < self.M:
                N = N-1
                while N in self.map:
                    N -= 1
                self.map[i] = N

        # print(self.map)
        # print(self.M)

    def pick(self):
        """
        :rtype: int
        """
        import  random
        res =random.randint(0,self.M-1)
        return self.map[res] if res in self.map else res

相关文章: