528. 按权重随机选择
题目有点考察设计的思路的问题但是核心还是在于如何实现映射,也就是实现按照给定概率的随机分布。这里采用了类似几何概率的思想,利用前缀数组容易得到几何的概率,然后我们直需要在区间内去随机生成,就可以保证了服从给定的概率分布。
然后利用二分查找可以找到小于这个数字的最大边界。
比如[1, 3] 就会presum = [1, 4]。那当index= 3 的时候就需要返回2,其实就是target>nums[mid]时候需要left = mid+1;而等于的时候可以直接返回。
class Solution {
// 使用前缀和,去解决了分段的问题。二分查找更快速的定位到对应的位置
private static Random random = new Random();
private int[] preSum;
public Solution(int[] w) {
this.preSum = new int[w.length];
this.preSum[0] = w[0];
for (int i = 1; i < w.length; i++) {
this.preSum[i] = this.preSum[i - 1] + w[i];
}
}
public int pickIndex() {
int max = this.preSum[this.preSum.length - 1];
int rand = random.nextInt(max) + 1;
return binarySearch(preSum, rand);
}
private int binarySearch(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (target < nums[mid]) {
right = mid-1;
} else if(target > nums[mid]){
left = mid+1;
}