Skip to content

Commit 060d205

Browse files
committed
Random Pick By Weight - Day 5
1 parent 896a320 commit 060d205

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.kishan.scala.leetcode.juneChallenges
2+
3+
import scala.util.Random
4+
5+
6+
/*
7+
* Given an array w of positive integers,
8+
* where w[i] describes the weight of index i,
9+
* write a function pickIndex which randomly picks an index in proportion to its weight.
10+
*
11+
*/
12+
13+
/*
14+
* Input:
15+
["Solution","pickIndex"]
16+
[[[1]],[]]
17+
Output: [null,0]
18+
*
19+
* Input:
20+
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
21+
[[[1,3]],[],[],[],[],[]]
22+
Output: [null,0,1,1,1,0]
23+
*/
24+
*/
25+
26+
27+
/*
28+
* Approach:
29+
*
30+
* 1. Calculation Running total for each element of the array.
31+
* 2. Generating a Random number using scala.util.Random (Including upper boundary Value).
32+
* 3. Using Binary Search Algorithm to search the range where the random number is located.
33+
* 4. Finally returning the upper boundary value of the range. Which is the result.
34+
*
35+
* */
36+
37+
/*
38+
* If Input: [8, 9]
39+
*
40+
* Running sum will be [8, 17]
41+
*
42+
* If our Random number lies between 1-8 we will pick the first index.
43+
* If our random number lies between 9-17 we will pick the second index
44+
*
45+
* We will ending up picking the index which has the highest probability
46+
*
47+
* */
48+
49+
50+
class RandomPickWithWeight(_w: Array[Int]) {
51+
52+
private val length = _w.length
53+
private val totalSum = _w.sum
54+
private val random = new Random()
55+
private var preSum: Array[Int] = _w.scan(0)((a, b) => a + b).drop(1)
56+
57+
def pickIndex(): Int = {
58+
val randomNumber = random.nextInt(totalSum) + 1
59+
var head = 0
60+
var tail = preSum.length - 1
61+
var mid: Int = head + (tail - head) / 2
62+
while (head < tail) {
63+
mid = head + (tail - mid) / 2
64+
if (randomNumber > preSum(mid)) {
65+
head = mid + 1
66+
} else {
67+
tail = mid
68+
}
69+
}
70+
return if (preSum(tail) >= randomNumber) tail else head
71+
}
72+
73+
74+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.kishan.scala.leetcode.juneChallenges
2+
3+
object RandomPickWithWeightTest {
4+
def main(args: Array[String]): Unit = {
5+
val input: Array[String] = Array("Solution", "pickIndex")
6+
val inputInt: Array[Int] = input.map(_.length)
7+
val r = new RandomPickWithWeight(inputInt)
8+
println(r.pickIndex())
9+
}
10+
}

0 commit comments

Comments
 (0)