1. 程式人生 > 其它 >按權重隨機選擇 -- LeetCode -- 8.30

按權重隨機選擇 -- LeetCode -- 8.30

按權重隨機選擇

給定一個正整數陣列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, 2, 3, 4];

  就可以有以下幾種情況:很直觀的就可以看出下標 0 出現的概率為 1 / 10, 3 出現的概率為 4 / 10;

0 1 2 3 4 5 6 7 8 9
0 1 1 2 2 2 3 3 3 3
  就可以用函式生成一個不大於 9 的隨機數;然後輸出它對應的下標就可以了;   具體則麼找到它的下標可以用字首和來實現,然後二分查詢;   這題用 STL 真方便!!!

程式碼:

  

class Solution {
public:
    vector<int> preSum;//字首和陣列
    Solution(vector<int>& w) {
        preSum = w;
        int size = w.size();
        for(int i = 1; i < size; i++){
            preSum[i] += preSum[i - 1];
        }
    }
    
    int pickIndex() {
        int p = rand() % preSum.back() + 1;
        int ans = lower_bound(preSum.begin(),preSum.end(),p) - preSum.begin();//使用二分查詢,找到第一個不小於 p 的值,然後輸出 preSum陣列的下標
        return ans;
    }
};