三亚高端服务网站,迪庆州住房和城乡建设局网站,在网站做直播,百度学术官网登录入口528. 按权重随机选择
给定一个正整数数组 w #xff0c;其中 w[i] 代表下标 i 的权重#xff08;下标从 0 开始#xff09;#xff0c;请写一个函数 pickIndex #xff0c;它可以随机地获取下标 i#xff0c;选取下标 i 的概率与 w[i] 成正比。
例如#xff0c;对于 w…528. 按权重随机选择
给定一个正整数数组 w 其中 w[i] 代表下标 i 的权重下标从 0 开始请写一个函数 pickIndex 它可以随机地获取下标 i选取下标 i 的概率与 w[i] 成正比。
例如对于 w [1, 3]挑选下标 0 的概率为 1 / (1 3) 0.25 即25%而选取下标 1 的概率为 3 / (1 3) 0.75即75%。
也就是说选取下标 i 的概率为 w[i] / sum(w) 。
示例 1
输入
[Solution,pickIndex]
[[[1]],[]]
输出
[null,0]
解释
Solution solution new Solution([1]);
solution.pickIndex(); // 返回 0因为数组中只有一个元素所以唯一的选择是返回下标 0。示例 2
输入
[Solution,pickIndex,pickIndex,pickIndex,pickIndex,pickIndex]
[[[1,3]],[],[],[],[],[]]
输出
[null,1,1,1,1,0]
解释
Solution solution new Solution([1, 3]);
solution.pickIndex(); // 返回 1返回下标 1返回该下标概率为 3/4 。
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 0返回下标 0返回该下标概率为 1/4 。由于这是一个随机问题允许多个答案因此下列输出都可以被认为是正确的:
[null,1,1,1,1,0]
[null,1,1,1,1,1]
[null,1,1,1,0,0]
[null,1,1,1,0,1]
[null,1,0,1,0,0]
......
诸若此类。提示
1 w.length 100001 w[i] 10^5pickIndex 将被调用不超过 10000 次
解题思路
维护一个前缀和数组里面的前缀和元素就是每个区间的边界因此我们随机生成一个[1,sum]之间的数字再根据这个数字在前缀和数组中用二分查找搜索其位于的区间
代码
class Solution {int[] pre;int sum;public Solution(int[] w) {int nw.length;prenew int[n];pre[0]w[0];for(int i1;in;i)pre[i]pre[i-1]w[i];sumpre[n-1];}public int pickIndex() {int idx(int)(Math.random()*sum)1;return bs(idx);}public int bs(int tar) {int l0,rpre.length-1;while(lr){int mid(r-l)/2l;if(pre[mid]tar){lmid1;}else {rmid;}}return l;}
}/*** Your Solution object will be instantiated and called as such:* Solution obj new Solution(w);* int param_1 obj.pickIndex();*/