# 【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++`