按权重随机选择
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 99 ms, 内存: 20.9 MB
/*
* 思路:
* 和Java版本一样,我们需要构建一个前缀和数组prefixSums。
* 不同之处在于我们将尽量使用Java Stream来构建前缀和数组。
*/
import java.util.*;
import java.util.stream.IntStream;
class Solution {
private int[] prefixSums;
private Random random;
public Solution(int[] w) {
prefixSums = new int[w.length];
prefixSums[0] = w[0];
IntStream.range(1, w.length).forEach(i -> prefixSums[i] = prefixSums[i - 1] + w[i]);
random = new Random();
}
public int pickIndex() {
int target = random.nextInt(prefixSums[prefixSums.length - 1]) + 1;
return IntStream.range(0, prefixSums.length)
.filter(i -> prefixSums[i] >= target)
.findFirst()
.orElse(-1);
}
}
解释
方法:
此题解采用了前缀和和二分搜索的方法来解决问题。首先,将输入权重数组转换为一个概率数组,该数组的每个元素表示从开始到当前位置的权重和占总权重的比例。具体操作是,在初始化函数中计算总权重,并构建一个概率数组,其中每个元素是到当前元素为止的权重和除以总权重。在pickIndex函数中,使用random.random()生成一个[0, 1)之间的随机数,然后通过二分搜索(bisect_left)找到这个随机数应该插入概率数组的位置,由于概率数组是累积的,这样可以保证按权重随机选择下标。
时间复杂度:
O(log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在初始化时,你创建了概率数组`self.prob`,它的第一个元素为0是出于什么考虑?
▷🦆
在构建概率数组时,将每个权重加到`temp`并更新`self.prob`,这种方法是否保证了概率分布正确反映权重的累积特性?
▷🦆
函数`pickIndex`中使用`random.random()`生成的随机数代表什么含义,它与权重分布的关系是怎样的?
▷