# 【LeetCode】 528. Random Pick with Weight ## Description > Given an array `w` of positive integers, where `w[i]` describes the weight of index `i`, write a function `pickIndex` which randomly picks an index in proportion to its weight. > Note: > 1. `1 <= w.length <= 10000` > 2. `1 <= w[i] <= 10^5` > 3. `pickIndex` will be called at most `10000` times. > Explanation of Input Syntax: > The input is two lists: the subroutines called and their arguments. `Solution`'s constructor has one argument, the array `w`. `pickIndex` has no arguments. Arguments are always wrapped with a list, even if there aren't any. > 給予一正整數陣列`w`,其中`w[i]`描述索引為`i`的權重。寫一個函式`pickIndex`會按照權重去隨機挑選一個索引。 > 注意: > 1. `1 <= w.length <= 10000` > 2. `1 <= w[i] <= 10^5` > 3. `pickIndex` 至少會被呼叫 `10000` 次。 > 輸入語法解釋: > 輸入會是兩個列表:哪些副程式被呼叫和它們的參數。 > `Solution`的建構子有一個參數:陣列`w`。`pickIndex`沒有參數。參數總是被包裝在列表中,即便沒有任何參數。 ## Example: ``` Example 1: Input: ["Solution","pickIndex"] [[[1]],[]] Output: [null,0] Example 2: Input: ["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"] [[[1,3]],[],[],[],[],[]] Output: [null,0,1,1,1,0] ``` ## Solution * 使用`rand()`可以得到一個隨機值,介於`0`到int的最大值。 * 給予權重時,使用另一個`vector`去儲存它;並將元素改為遞增。 * 如果權重為`[1, 2, 3]`,新的`vector`為`[1, 3, 6]`。 * 接著我們將`rand() % sum(w)`,可以得到一個`0 ~ sum(w)`的數字。 * 最後去找這個隨機數落在`vector`的哪個區間,就代表選到哪個數字。 * 權重越大的索引,對應到的區間也越大,所以越容易被選中,藉此達到權重隨機。 * 下方code中,search的部分使用線性搜尋,可改用二分搜尋來加速。 ### Code ```C++=1 class Solution { public: Solution(vector<int>& w) { int sum = 0; for(int i = 0; i < w.size(); i++) { sum += w[i]; this->w.push_back(sum); } } int pickIndex() { int r = rand() % w.back(); for(int i = 0; i < w.size(); i++) if(r < w[i]) return i; return w.size() - 1; } private: vector<int> w; }; /** * Your Solution object will be instantiated and called as such: * Solution* obj = new Solution(w); * int param_1 = obj->pickIndex(); */ ``` ###### tags: `LeetCode` `C++`