p382

LeetCode 382 Linked List Random Node 题解

1.题目:

Given a singly linked list, return a random node’s value from the linked list. Each node must have the same probability of being chosen.
Follow up:
What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?
Example:
// Init a singly linked list [1,2,3].
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
Solution solution = new Solution(head);
// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();

题意:

输入一个链表,你不知道长度,随机的返回链表中的值,使它们的概率相等。

2.解题思路:

首先说两点要注意的,给你的测试用例以及应该返回的值是随机的。 不要直接使用head.
现在开始说解题思路,我决定把这个思路的推理过程翻译成白话文,因为智障的我没有看懂维基百科,想了好久。
思路很简单从i=1开始累计,每次从[0,i)中随机取一个数,如果这个数为0,则将答案设置为此时的节点值。
现在进行推理,从i=1,时 只能取0,概率为1/1。之后i=2,概率为1/2,所以分给之前不被覆盖的概率为1/2.再i=3,分给之前不被覆盖的概率为2/3,
这两份对于1,2均等,所以这三份均等。这样可以一直推理下去,可以用数学归纳法证明。

3.代码


[title] [] [url] [link text]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {

private ListNode head = null;
private Random random = null;

/**
* @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 head) {
this.head = head;
random = new Random();
}

/** Returns a random node's value. */
public int getRandom() {
int ans = 0;
ListNode listNode = head;
int i = 1;
while (listNode != null) {
if (random.nextInt(i) == 0) {
ans = listNode.val;
}
listNode = listNode.next;
i++;
}

return ans;

}
}

/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(head);
* int param_1 = obj.getRandom();
*/


4.一些总结: