[LeetCode] Random Pick with Weight 根据权重随机取点
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 <= w.length <= 100001 <= w[i] <= 10^5pickIndexwill be called at most10000times.
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.
这道题给了一个权重数组,让我们根据权重来随机取点,现在的点就不是随机等概率的选取了,而是要根据权重的不同来区别选取。比如题目中例子2,权重为 [1, 3],表示有两个点,权重分别为1和3,那么就是说一个点的出现概率是四分之一,另一个出现的概率是四分之三。由于我们的rand()函数是等概率的随机,那么我们如何才能有权重的随机呢,我们可以使用一个trick,由于权重是1和3,相加为4,那么我们现在假设有4个点,然后随机等概率取一个点,随机到第一个点后就表示原来的第一个点,随机到后三个点就表示原来的第二个点,这样就可以保证有权重的随机啦。那么我们就可以建立权重数组的累加和数组,比如若权重数组为 [1, 3, 2] 的话,那么累加和数组为 [1, 4, 6],整个的权重和为6,我们 rand() % 6,可以随机出范围 [0, 5] 内的数,随机到 0 则为第一个点,随机到 1,2,3 则为第二个点,随机到 4,5 则为第三个点,所以我们随机出一个数字x后,然后再累加和数组中查找第一个大于随机数x的数字,使用二分查找法可以找到第一个大于随机数x的数字的坐标,即为所求,参见代码如下:
解法一:
class Solution {
public:
Solution(vector<int> w) {
sum = w;
for (int i = ; i < w.size(); ++i) {
sum[i] = sum[i - ] + w[i];
}
}
int pickIndex() {
int x = rand() % sum.back(), left = , right = sum.size() - ;
while (left < right) {
int mid = left + (right - left) / ;
if (sum[mid] <= x) left = mid + ;
else right = mid;
}
return right;
}
private:
vector<int> sum;
};
我们也可以把二分查找法换为STL内置的upper_bound函数,根据上面的分析,我们随机出一个数字x后,然后再累加和数组中查找第一个大于随机数x的数字,使用二分查找法可以找到第一个大于随机数x的数字的坐标。而upper_bound() 函数刚好就是查找第一个大于目标值的数,lower_bound() 函数是找到第一个不小于目标值的数,用在这里就不太合适了,关于二分搜索发的分类可以参见博主之前的博客LeetCode Binary Search Summary 二分搜索法小结,参见代码如下:
解法二:
class Solution {
public:
Solution(vector<int> w) {
sum = w;
for (int i = ; i < w.size(); ++i) {
sum[i] = sum[i - ] + w[i];
}
}
int pickIndex() {
int x = rand() % sum.back();
return upper_bound(sum.begin(), sum.end(), x) - sum.begin();
}
private:
vector<int> sum;
};
讨论:这题有个很好的follow up,就是说当weights数组经常变换怎么办,那么这就有涉及到求变化的区域和问题了,在博主之前的一道 Range Sum Query - Mutable 中有各种方法详细的讲解。只要把两道题的解法的精髓融合到一起就行了,可以参见论坛上的这个帖子。
类似题目:
Random Point in Non-overlapping Rectangles
参考资料:
https://leetcode.com/problems/random-pick-with-weight/discuss/154024/JAVA-8-lines-TreeMap
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Random Pick with Weight 根据权重随机取点的更多相关文章
- [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 ...
- 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 ...
- select random item with weight 根据权重随机选出
http://eli.thegreenplace.net/2010/01/22/weighted-random-generation-in-python/ 类似俄罗斯轮盘赌
- [LeetCode] Random Pick with Blacklist 带黑名单的随机选取
Given a blacklist B containing unique integers from [0, N), write a function to return a uniform ran ...
- LeetCode 528. Random Pick with Weight
原题链接在这里:https://leetcode.com/problems/random-pick-with-weight/ 题目: Given an array w of positive inte ...
- 528. Random Pick with Weight
1. 问题 给定一个权重数组w,w[i]表示下标i的权重,根据权重从数组中随机抽取下标. 2. 思路 这道题相当于 497. Random Point in Non-overlapping Recta ...
- [Swift]LeetCode528. 按权重随机选择 | Random Pick with Weight
Given an array w of positive integers, where w[i] describes the weight of index i, write a function ...
- 【LeetCode】528. Random Pick with Weight 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/random-pi ...
- [LeetCode] Random Pick Index 随机拾取序列
Given an array of integers with possible duplicates, randomly output the index of a given target num ...
随机推荐
- 第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)
一. 并行编程 1. 区分串行编程和串行编程 ①. 串行编程:所谓的串行编程就是单线程的作用下,按顺序执行.(典型代表for循环 下面例子从1-100按顺序执行) ②. 并行编程:充分利用多核cpu的 ...
- 第十三节:Lambda、linq、SQL的相爱相杀(2)
一. Linq开篇 1.Where用法 linq中where的用法与SQL中where的用法基本一致. #region 01-where用法 { //1. where用法 //1.1 查询账号为adm ...
- mysql用户管理与备份
用户管理 我们知道在Mysql中root用户是最高权限的用户,其他用户的创建和权限授予都是通过root用户来操作的 查看用户 在root用户界面下 select user,host,password ...
- DUMP101 企业级电商FE
需求拆分原则 1. 单个迭代不能太大 2. 需求可交付,功能闭环 3. 成本意识 二八法则 4. 预期价值体现 ……………………………………………………………………………… 做 [直接 git cl ...
- Coursera, Big Data 3, Integration and Processing (week 1/2/3)
This is the 3rd course in big data specification courses. Data model reivew 1, data model 的特点: Struc ...
- 消除导入MNIST数据集发出的警告信息
原本导入数据集你仅需这样: # Import MNIST data from tensorflow.examples.tutorials.mnist import input_data mnist = ...
- mui上拉刷新+下拉加载
具体操作见代码: <!doctype html> <html> <head> <meta charset="UTF-8"> < ...
- python之造测试数据-faker(转载)
在软件需求.开发.测试过程中,有时候需要使用一些测试数据,针对这种情况,我们一般要么使用已有的系统数据,要么需要手动制造一些数据. 在手动制造数据的过程中,可能需要花费大量精力和工作量,现在好了,有一 ...
- 史上最污技术解读,让你秒懂IT术语(转载)
假设你是一位妹子,你的男友沉迷游戏经常不接电话无故宕机,所以当你们约好下午逛街以后你要时不时地打个电话询问,看看他是不是还能正常提供服务,这叫心跳检测. 假设你是一位妹子,你想去逛街而你的男友A在打游 ...
- [Kubernetes]yaml文件详解
应前一段时间夸下的海口:[Kubernetes]如何使用yaml文件使得可以向外暴露服务,说过要写一篇关于yaml文件详解的文章出来的,今天来总结一下.yaml文件用在很多地方,但是这里以介绍在Kub ...