# 382. Linked List Random Node

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();
``````

``````class Solution {
public:
Solution(ListNode* head) {
len = 0;
ListNode *cur = head;
this->head = head;
while (cur) {
++len;
cur = cur->next;
}
}
int getRandom() {
int t = rand() % len;
ListNode *cur = head;
while (t) {
--t;
cur = cur->next;
}
return cur->val;
}
private:
int len;
ListNode *head;
};
``````

Follow up 中说链表可能很长，我们没法提前知道长度，这里用到了著名了 水塘抽样 Reservoir Sampling 的思路，由于限定了 head 一定存在，所以先让返回值 res 等于 head 的节点值，然后让 cur 指向 head 的下一个节点，定义一个变量i，初始化为2，若 cur 不为空则开始循环，在 [0, i - 1] 中取一个随机数，如果取出来0，则更新 res 为当前的 cur 的节点值，然后此时i自增一，cur 指向其下一个位置，这里其实相当于维护了一个大小为1的水塘，然后随机数生成为0的话，交换水塘中的值和当前遍历到的值，这样可以保证每个数字的概率相等，参见代码如下：

``````class Solution {
public:
Solution(ListNode* head) {
this->head = head;
}
int getRandom() {
int res = head->val, i = 2;
ListNode *cur = head->next;
while (cur) {
int j = rand() % i;
if (j == 0) res = cur->val;
++i;
cur = cur->next;
}
return res;
}
private:
ListNode *head;
};
``````

Github 同步地址：

https://github.com/grandyang/leetcode/issues/382

Random Pick Index

https://leetcode.com/problems/linked-list-random-node/

https://leetcode.com/problems/linked-list-random-node/discuss/85662/Java-Solution-with-cases-explain

https://leetcode.com/problems/linked-list-random-node/discuss/85659/Brief-explanation-for-Reservoir-Sampling

https://leetcode.com/problems/linked-list-random-node/discuss/85701/O(n)-Time-and-O(1)-Space-Java-Solution

https://leetcode.com/problems/linked-list-random-node/discuss/85690/using-reservoir-sampling-o1-space-on-time-complexityuff0cc

LeetCode All in One 题目讲解汇总(持续更新中…)

 微信打赏 Venmo 打赏
（欢迎加入博主的知识星球，博主将及时答疑解惑，并分享刷题经验与总结，试运营期间前五十位可享受半价优惠～）

×

Help us with donation