398. Random Pick Index

1. 问题

对于一个可能包含重复数字的数组,给定一个目标数,随机返回该目标数的下标。

2. 思路

很直接的做法是,构建一个字典,键为目标数,值为一个数组,存储的是目标数在原数组中出现过的位置下标。
每次输入一个目标数,直接根据目标数得到下标数组,然后在这个下标数组中随机取一个下标即可。

init:时间复杂度O(n),空间复杂度O(n)
pick:时间复杂度O(1),空间复杂度O(1)

也可以用蓄水池采样的方法,具体介绍见382. Linked List Random Node(蓄水池采样)

pick:时间复杂度O(n),空间复杂度O(1)

3. 代码

用字典保存每个目标数对应的下标数组,每次取的时候,根据目标数找到下标数组,在数组中随机取一个下标

class Solution(object):
    def __init__(self, nums):
        self.num_indexes = {}
        for i,num in enumerate(nums):
            if(self.num_indexes.get(num) != None):
                self.num_indexes.get(num).append(i)
            else:
                self.num_indexes[num] = [i]

    def pick(self, target):
        indexes = self.num_indexes[target]
        return indexes[random.randint(0, len(indexes)-1)]
        
# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.pick(target)

蓄水池采样

import random
class Solution(object):
    def __init__(self, nums):
        self.nums = nums

    def pick(self, target):
        count = 1
        for i,num in enumerate(self.nums):
            if(num != target):
                continue
            if(random.random() < 1.0 / count):
                index = i
            count += 1
        return index

4. 类似题目

382. Linked List Random Node(蓄水池采样)

posted @ 2018-10-25 22:53 PilgrimHui 阅读(...) 评论(...) 编辑 收藏