周日来了题中等的。
行吧,来者不拒。
1、先看题
首先这题我是每太看懂的,但题目加粗标明了要求每个节点被选中的概率一样,所以就觉得大概是和数学相关的题了。
2、思路
关于链表的使用应该是很基础的内容,大学如果学了计算机的话,《数据结构》这门课是一定会讲到的。
于是重点就在于如何让每次选中的节点概率一样了。
然鹅,数学题我是一概不会的,交给Random好了,毕竟只要我不加什么限制,在量级够大的情况下,随机就能让每个节点被选中的概率一致(大概吧 )。
总之,就是本着这种想法我就开动了。而至于节点的数量范围,不使用额外空间等要求,也很好办。
3、动手!
class Solution {
private int length;
private ListNode prev;
private Random random;
public Solution(ListNode head) {
prev = head;
length = 1;
while (prev.next != null) {
length++;
prev = prev.next;
}
//让链表形成环状
prev.next = head;
random = new Random();
}
public int getRandom() {
int move = random.nextInt(length);
while (move > 0) {
prev = prev.next;
move--;
}
return prev.val;
}
}
4、解读
是的!我选择了使用环状链表!
只要让链表最后一个节点的下一个节点(本应为null
)指向链表的头节点,辣么这个链表就会形成环状链表。
然后再让一个指针不停在这个环状链表上移动,根据每次Random
生成的随机数,并移动相同长度,再返回当前指向的节点的值即可。
这样,你甚至不用处理重新指回头部的情况。
至于这样的返回,能否保证选中每个节点的概率一致就……管他呢?
5、提交
额……我觉得这题力扣根本没法校验选中节点的概率是否一致,毕竟在完全随机的情况下,它没法根据我们的返回来做判断,更别提分析我们的代码了。
6、学习
直接来看大牛们好了,毕竟题目标签里的“水塘抽样”想必吸引你很久了。
嗯……果然看不懂。
你的朋友可能会背叛你,你的亲人可能会背叛你,但数学不会,数学不会就是不会。
这位大牛贴出了比官解更详细的水塘抽样讲解,供大家学习参考。
7、总结
啊……怎么周末又要过完了……
但总之,今天这道数学题还是有些含金量的,花些时间来消化消化吧。