力扣382 链表随机节点(水塘抽样)
作者:互联网
题目:
原本我是用一个链表遍历的方法做的,但看了题解的水塘抽样算法,就去搜索学习了该算法,并最后用该算法实现了这个题目,所以我打算用水塘抽样的方法分析
首先了解一下这个算法
水塘抽样是一系列的随机算法,其目的在于从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数量,尤其适用于不能把所有n个项目都存放到内存的情况。
算法步骤如下:
1、从S中抽取首k项放入k容量的集合「水塘」中
2、对于每一个S[j]项(j ≥ k),随机产生一个范围从0到j的整数r,若 r < k 则把水塘中的第r项换成S[j]项,遍历完所有n项完成随机。
此时每一项最终被选取到得概率是
要实现这个算法,就需要随机产生一个从0到j的整数,这时候我们需要用到Randam.nextInt()这个方法。该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
代码:
public Solution(ListNode head) {
this.head = head;
random = new Random();
}
public int getRandom() {
int i = 1, a = 0;
for (ListNode node = head; node != null; node = node.next) {
if (random.nextInt(i) == 0) { // 1/i 的概率选中(替换为答案)
a = node.val;
}
i++;
}
return a;
}
Solution是该类的一个构造函数,getRandom方法通过遍历每一个结点,一开始默认为第一个节点的值,随着i的增加,值可能发生改变也可能不改变。
标签:node,力扣,head,水塘,int,算法,链表,382,随机 来源: https://blog.csdn.net/yyswit/article/details/122529591