Reservoir Sampling (Java) - ShuweiLeung/Thinking GitHub Wiki
1.(398:Medium)(非常经典题)Random Pick Index
- randomly select an int from 0 to the nums of target. If x equals 0, set the res as the current index. The probability is always 1/nums for the latest appeared number. For example, 1 for 1st num, 1/2 for 2nd num, 1/3 for 3nd num (1/2 * 2/3 for each of the first 2 nums).
int x = rand.nextInt(++total);
int[] nums;
Random rand;
public _398_RandomPickIndex(int[] nums) {
this.nums = nums;
this.rand = new Random();
}
public int pick(int target) {
int total = 0;
int res = -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
// randomly select an int from 0 to the nums of target. If x equals 0, set the res as the current index. The probability is always 1/nums for the latest appeared number. For example, 1 for 1st num, 1/2 for 2nd num, 1/3 for 3nd num (1/2 * 2/3 for each of the first 2 nums).
int x = rand.nextInt(++total);
res = x == 0 ? i : res;
}
}
return res;
}
2.(384:Medium)(经典题)Shuffle an Array
- 思路:每次往后读取数组的时候,当读到第i个的时候以1/i的概率随机替换1~i中的任何一个数,这样保证最后每个数字出现在每个位置上的概率都是相等的。即,总是从前j个数中选取一个数字i,放置到当前位置上。
3.(382:Medium)(非常经典题)Linked List Random Node
- 也是应用reservoir sampling思想进行求解,代码如下:
ListNode head;
Random random;
/** @param head The linked list's head.
Note that the head is guaranteed to be not null, so it contains at least one node. */
public Solution(ListNode h) {
head = h;
random = new Random();
}
/** Returns a random node's value. */
public int getRandom() {
ListNode c = head;
int r = c.val;
for(int i=1;c.next != null;i++){
c = c.next;
//if(random.nextInt(i + 1) == i) r = c.val; //随机数等于i也行
if(random.nextInt(i + 1) == 0) r = c.val;
}
return r;
}