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) 。

该题的关键还是找准随机值该插入的位置,还有随机值选取的范围。范围为总和,插入位置找准就行。

/*
    代码包含开始写的循环的方法和改进的使用二分法的方法
*/
class Solution {
    int []pre;

    public Solution(int[] w) {
        pre = new int[w.length];
        pre[0] = w[0]; 
        for(int i = 1; i < w.length; i++){
            pre[i] = pre[i - 1] + w[i];
        }
    }
    
    public int pickIndex() {
        //int n1 = 0;
         int n = new Random().nextInt(pre[pre.length - 1]);
        // for(int i = 1; i < pre.length; i++){
        //     if(n >= pre[i-1] && n < pre[i]){
        //         n1 = i;
        //         break;
        //     }
        // }
        return binarySearch(n);
    }

    private int binarySearch(int x) {
        int low = 0, high = pre.length - 1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            if (pre[mid] <= x) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return low;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(w);
 * int param_1 = obj.pickIndex();
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值