LeetCode第 528 题:按权重随机选择(C++)

528. 按权重随机选择 - 力扣(LeetCode)

还是类似蓄水池抽样问题:

LeetCode第 382 题:链表随机节点(C++)_zj-CSDN博客
LeetCode第 398 题:随机数索引(C++)_zj-CSDN博客

这儿需要考虑数组值,也就是权重,权重越大,被选取的概率也就越大。

但是代码一直超时。。。

class Solution {
public:
    Solution(vector& w) {
        p = &w;
    }
    
    int pickIndex() {//返回值应该是位置(下标)
        int sum = 0, res = 0;//pre记录上一次的sum
        for(int i = 0; i < p->size(); ++i){
            sum += (*p)[i];
            if(rand()%sum >= sum - p[i])   res = i;
        }
        return res;
    }
private:
    vector* p;
};

好吧,看了题解之后才发现理解错题意了。这题并不像蓄水池抽样问题,也没有提到数组很大或者数据流之类的字眼。所以前缀和 + 二分就可以:

class Solution {
public:
    Solution(vector& w){
        //最后p里面存储的是w的前缀和,因为元素是正整数
        //所以p的首元素为最小值,尾元素为最大值
        p = w;
        for(int i = 1; i < p.size(); ++i)   p[i] = p[i] + p[i-1];//累加
    }
    
    int pickIndex() {//返回值应该是位置(下标)
        int i = rand() % p.back()+1;//随机1~p.back()之间的某个数
        return lower_bound(p.begin(), p.end(), i) - p.begin();//二分
    }
private:
    vector p;
};

你可能感兴趣的:(leetcode,leetcode)