题目描述:
LeetCode 398. Random Pick Index
Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array.
Note:
The array size can be very large. Solution that uses too much extra space will not pass the judge.
Example:
int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. solution.pick(3); // pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1);
题目大意:
给定一个可能包含重复元素的整数数组,给定一个目标数,随机输出其下标。你可以假设给定的目标数一定存在于数组中。
注意:
数组长度可能很大。使用较多额外空间的解决方案无法通过系统测试。
解题思路:
利用链表(Linked List)数据结构
初始化:
数组next记录当前下标的下一个下标;
字典head记录目标数target对应链表头部的数组下标
随机选取:
首先找到target对应的数组下标链表的头部,记为head
然后从head开始,通过next数组遍历一遍链表,求出链表长度,记为cnt
接下来随机选取0到cnt之间的数,记为c
最后从head开始,越过c-1个节点,将该节点返回
Python代码:
class Solution(object):
def __init__(self, nums):
"""
:type nums: List[int]
:type numsSize: int
"""
size = len(nums)
self.next = [0] * (size + 1)
self.head = collections.defaultdict(int)
for i, n in enumerate(nums):
self.next[i + 1] = self.head[n]
self.head[n] = i + 1
def pick(self, target):
"""
:type target: int
:rtype: int
"""
cnt = 0
idx = self.head[target]
while idx > 0:
cnt += 1
idx = self.next[idx]
c = int(random.random() * cnt)
idx = self.head[target]
for x in range(c):
idx = self.next[idx]
return idx - 1
本文链接:http://bookshadow.com/weblog/2016/09/11/leetcode-random-pick-index/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。