Skip to content

Conversation

@syoshida20
Copy link
Owner

@syoshida20 syoshida20 commented Apr 24, 2025

問題URL

https://leetcode.com/problems/random-pick-with-weight/

問題文

You are given a 0-indexed array of positive integers w where w[i] describes the weight of the ith index.
You need to implement the function pickIndex(), which randomly picks an index in the range [0, w.length - 1] (inclusive) and returns it. The probability of picking an index i is w[i] / sum(w).
For example, if w = [1, 3], the probability of picking index 0 is 1 / (1 + 3) = 0.25 (i.e., 25%), and the probability of picking index 1 is 3 / (1 + 3) = 0.75 (i.e., 75%).

Example 1:

  • Input
    ["Solution","pickIndex"]
    [[[1]],[]]

  • Output
    [null,0]

  • Explanation
    Solution solution = new Solution([1]);
    solution.pickIndex(); // return 0. The only option is to return 0 since there is only one element in w.

Example 2:

  • Input
    ["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
    [[[1,3]],[],[],[],[],[]]

  • Output
    [null,1,1,1,1,0]

  • Explanation
    Solution solution = new Solution([1, 3]);
    solution.pickIndex(); // return 1. It is returning the second element (index = 1) that has a probability of 3/4.
    solution.pickIndex(); // return 1
    solution.pickIndex(); // return 1
    solution.pickIndex(); // return 1
    solution.pickIndex(); // return 0. It is returning the first element (index = 0) that has a probability of 1/4.

Since this is a randomization problem, multiple answers are allowed.
All of the following outputs can be considered correct:
[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]
......
and so on.

Constraints:

1 <= w.length <= 104
1 <= w[i] <= 105
pickIndex will be called at most 104 times.

@syoshida20 syoshida20 self-assigned this May 1, 2025
@syoshida20 syoshida20 marked this pull request as ready for review May 2, 2025 13:51
* 発想
* 重み付きの確率を行う方法。
* `w_0`, `w_1`, `w_2`, ...をsumで割り算し`w_0`/sum, `w_1`/sum, `w_2`/sum, ...とした後に、累積和をとる。
0から1のランダムな値がどの重みに属するかを調べることで、重みを考慮したサンプリングできそう。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確率だからよいかと思う一方で、浮動小数点は色々なことが起きるので、自然数で処理したほうが私は好みです。

Copy link
Owner Author

@syoshida20 syoshida20 May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 浮動小数点の懸念事項
  • 整数で解く方法

を意識ができておりませんでした。ご指摘、ありがとうございます。

懸念項目の一例を調べました。

  • 丸誤差
    • 有効数字の桁が落ちる
    • 情報が落ちる
  • 演算の順序性が保たれない

参考:

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6643657 で整数で解く方法を追加しました。

sum += weight_i
}
for (let i=0; i<w.length; i++) {
n const weight_i = w[i]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

謎の n。これを置き直してもあまりいいことないでしょう。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wという変数が重み( weight )を表すことは自明ということですね。

## その他の解法

* 二分探索のターゲットを変更する。
* 見つけたいターゲット: i-1番目の累積和 <= `random_value` < i番目の累積和となるiの値 (先ほどは、 i-1 < `random_value` <= iで等号の場所を変更した)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

等号はこっちのほうが自然でしょうね。Math.random は 0 は入って 1 は入らないので。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • random_valueが1を含む場合には、<=としてあげないと、1が出た際のiが見つからなくなる.
  • random_valueが1を含まない場合には、 <=としても1がそもそも出ないとで等号が使われない。

と理解しました。

* 二分探索において、ターゲットと引き継ぎ条件を考えることで、
left,rightの設定や等号の有無について迷わなくなった。

* 前のレビュー依頼から時間が空いてしまったので、もう一度習慣化する。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そうですね。1週間休んでも終わるのが1週間遅れるだけですが、頻度が半分になると時間が倍になりますからね。特に問題ないので進みましょう。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

はい、自分ができるペースで、頻度を意識してコーディング練習会に臨もうと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants