题目链接:
力扣https://leetcode-cn.com/problems/linked-list-random-node/
【分析】方法一 把链表中的点存在数组中,每次随机一个下标
class Solution {
List<Integer> list = new ArrayList();
int n = 0;
public Solution(ListNode head) {
while(head != null){
list.add(head.val);
head = head.next;
++n;
}
}
public int getRandom() {
return list.get((int)(Math.random() * n));
}
}
【方法二 水塘采样】适用于不知道链表中存了多少元素,并且通过链表存不下全部元素的情况,边枚举边保证采样的概率是1/n,具体算法为对于第i个元素,生成一个[0, i)的随机数r,如果这个r<1,这个点就被选中。
class Solution {
Random random = new Random();
ListNode head;
public Solution(ListNode head) {
this.head = head;
}
public int getRandom() {
int i = 0, ans = 0;
ListNode node = head;
while(node != null){
if(random.nextInt(++i) < 1) ans = node.val;
node = node.next;
}
return ans;
}
}