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