Leetcode Java Random Pick with Weight
업데이트:
문제
코드
class Solution {
private Random random;
private int[] sum;
private int length;
public Solution(int[] w) {
this.random = new Random();
for (int i = 1; i < w.length; ++i) {
w[i] += w[i - 1];
}
this.sum = w;
this.length = w.length;
}
public int pickIndex() {
int left = 0;
int right = this.length - 1;
int index = this.random.nextInt(this.sum[this.length - 1]) + 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (this.sum[mid] == index) {
return mid;
} else if (this.sum[mid] < index) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(w);
* int param_1 = obj.pickIndex();
*/
결과
설명
- w 내 값을 저장하고 임의 확률대로 반환하는 Solution 객체를 완성하는 문제이다.
- 생성자인 Solution(int[] w)은 w를 이용하여 객체를 초기화한다.
- 메서드인 pickIndex()는 아래의 확률대로 w 내 임의 값을 반환하는 역할을 수행한다.
- w 내 모든 값의 합을 sum이라 할 때, w[i]의 선택 확률은 $\frac{w[i]}{sum}$
- 문제 풀이에 필요한 전역 변수를 정의한다.
- random은 임의 확률로 값을 반환하기 위한 변수이다.
- sum은 생성자를 통해 주입된 w의 각 요소 별 누계를 넣어 저장할 배열이다.
- length는 생성자를 통해 주입된 w의 길이를 저장할 변수이다.
- 생성자인 Solution(int[] w)을 완성한다.
- random에 java의 Random 객체로 초기화한다.
- w를 반복하여 이전 값을 누계한 후 sum에 넣어준다.
- length에 w의 길이를 넣어 초기화한다.
- 메서드인 pickIndex()를 완성한다.
- left에 0, right에 $length - 1$을 넣어 초기화한다.
- index에 random을 활용하여 0부터 sum의 가장 큰 값 사이의 임의 값을 가져와 1을 더한 값을 넣어준다.
- left가 right 미만일 때 까지 반복하여 아래를 수행하여 탐색을 수행한다.
- mid에 $left + \frac{right - left}{2}$를 넣어준다.
- sum의 mid번째 값이 index인 경우, mid를 반환한다.
- sum의 mid번째 값이 index보다 작은 경우, left에 $mid + 1$을 넣어 값의 범위를 좁혀준다.
- sum의 mid번째 값이 index보다 큰 경우, right에 mid를 넣어 값의 범위를 좁혀준다.
- 반복이 완료되면 index 값에 가까운 값이 계산된 위치인 left를 반환한다.
소스
Sample Code는 여기에서 확인 가능합니다.
댓글남기기