作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/random-pick-with-weight/description/

题目描述:

Given an array w of positive integers, where w[i] describes the weight of index i, write a function pickIndex which randomly picks an index in proportion to its weight.

Note:

  1. 1 <= w.length <= 10000
  2. 1 <= w[i] <= 10^5
  3. pickIndex will be called at most 10000 times.

Example 1:

Input:
["Solution","pickIndex"]
[[[1]],[]]
Output: [null,0]

Example 2:

Input:
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output: [null,0,1,1,1,0]

Explanation of Input Syntax:

The input is two lists: the subroutines called and their arguments. Solution’s constructor has one argument, the array w. pickIndex has no arguments. Arguments are always wrapped with a list, even if there aren’t any.

题目大意

这个题目不太好理解,是要求按照权重挑选索引。比如[1,99]中,有1%的概率挑选到索引0,有99%的概率挑选到索引1.

解题方法

这个题很巧妙,我是想不出来的。做法是把概率分布函数转化为累计概率分布函数。然后通过随机数,进行二分查找。

比如,输入是 [1,2,3,4] ,那么概率分布是 [1/10, 2/10, 3/10, 4/10],累积概率分布是[1/10, 3/10, 6/10, 10/10] . 总和是 10。如果我们产生一个随机数,在 1~10 之中,然后判断这个数字在哪个区间中就能得到对应的索引。

对于输入 [1,2,3,4],计算出来的 preSum 是 [1,3,6,10] ,然后随机选一个 s,然后查找 s 属于哪个区间,各区间的含义是:

区间:		[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]
preSum: 1, 3, 6, 10
返回值: 1, 2, 3, 4

相当于找比 s 大的 preSum 值的索引。

如果还不理解,那么就想一想这个 preSum 的间隔,是不是发现这个间隔对应了题目的输入?那么选随机数找 upper_bound 的时候那就不是把一个区间里的数字合并到了某个 preSum 值上,而且 preSum 是不是对应着输入?所以是不是就把这个某个区间内的随机数对应上了一个输入值?

总之,随机的数字在哪个区间当中,那么就返回这个区间对应的数字即可。

这个二分查找也可以好好学习一下。

代码如下:

class Solution:

    def __init__(self, w):
"""
:type w: List[int]
"""
self.preSum = [0] * len(w)
self.preSum[0] = w[0]
for i in range(1, len(w)):
self.preSum[i] = self.preSum[i - 1] + w[i] def pickIndex(self):
"""
:rtype: int
"""
total = self.preSum[-1]
rand = random.randint(0, total - 1)
left, right = 0, len(self.preSum) - 1
while left + 1 < right:
mid = (left + right) // 2
if rand >= self.preSum[mid]:
left = mid
else:
right = mid
if rand < self.preSum[left]:
return left
return right # Your Solution object will be instantiated and called as such:
# obj = Solution(w)
# param_1 = obj.pickIndex()

日期

2018 年 8 月 18 日 —— 天在下雨

【LeetCode】528. Random Pick with Weight 解题报告(Python)的更多相关文章

  1. LeetCode 528. Random Pick with Weight

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

  2. [leetcode]528. Random Pick with Weight按权重挑选索引

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

  3. 【LeetCode】1046. Last Stone Weight 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆 日期 题目地址:https://leetco ...

  4. 528. Random Pick with Weight index的随机发生器

    [抄题]: Given an array w of positive integers, where w[i] describes the weight of index i, write a fun ...

  5. 528. Random Pick with Weight

    1. 问题 给定一个权重数组w,w[i]表示下标i的权重,根据权重从数组中随机抽取下标. 2. 思路 这道题相当于 497. Random Point in Non-overlapping Recta ...

  6. 【LeetCode】206. Reverse Linked List 解题报告(Python&C++&java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 [LeetCode] 题目地址:h ...

  7. 【LeetCode】654. Maximum Binary Tree 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

  8. 【LeetCode】784. Letter Case Permutation 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 循环 日期 题目地址:https://leet ...

  9. 【LeetCode】760. Find Anagram Mappings 解题报告

    [LeetCode]760. Find Anagram Mappings 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/find ...

随机推荐

  1. JAVA写入TXT

    用java生成txt文件有两种方式: 1)是通过字符流(或字节流): 2)是直接调用PrintWriter类. 具体实现过程如下: 1)字符流(字节流) 代码如下: import java.io.Fi ...

  2. 05 Windows安装python3.6.4+pycharm环境

    windows安装python3.6.4环境 使用微信扫码关注微信公众号,并回复:"Python工具包",免费获取下载链接! 一.卸载python环境 卸载以下软件: 二.安装py ...

  3. 逻辑学与Prolog学习笔记

    int a = 3 + 5; 很自然.如果Matrix a, b要加呢?没有运算符重载,a + b是不行的,只能add(a, b). int a = add(3, 5)也行.如果函数名可以用+呢?+( ...

  4. day05文件编辑命令

    day05文件编辑命令 mv命令:移动文件 mv命令:mv命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中. 格式:mv [原来的文件路径] [现在的文件路径] mv命令后面既可以跟 ...

  5. Identity Server 4 从入门到落地(八)—— .Net Framework 客户端

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  6. Can references refer to invalid location in C++?

    在C++中,引用比指针更加的安全,一方面是因为引用咋定义时必须进行初始化,另一方面是引用一旦被初始化就无法使其与其他对象相关联. 但是,在使用引用的地方仍然会有一些例外. (1)Reference t ...

  7. 3.3 GO字符串处理

    strings方法 index 判断子字符串或字符在父字符串中出现的位置(索引)Index 返回字符串 str 在字符串 s 中的索引( str 的第一个字符的索引),-1 表示字符串 s 不包含字符 ...

  8. Reactor之发射器(Flux、Mono)转换操作函数

    数据合并函数 由于业务需求有的时候需要将多个数据源进行合并,Reactor提供了concat方法和merge方法: concat public static <T> Flux<T&g ...

  9. RestTemplate进行访问分页PageInfo

    废话少说,给你们看代码: //provide的controller @ResponseBody @RequestMapping(value = "details",method = ...

  10. ssm中的模糊查询

    1.首先是数据层接口协议 public List<User> looks(String uname); 2.数据层实现 <select id="looks" re ...