# LeetCode 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.

## 示例

// Init a singly linked list [1,2,3].

// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();

## 限制条件

What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?

## 解题思路

#### 参考思路：

Reservoir Sampling是水塘抽样算法（又叫蓄水池抽样算法）。这个算法用在这道题上的思想是：在具有n$n$个元素的链表中，对于第m$m$个元素，以1m$\frac {1}{m}$的概率选择它，有m1m$\frac {m-1}{m}$不被选择。这样每一个元素被选中的概率都是1n$\frac {1}{n}$。证明如下：

m$m$个元素最后被选中的概率 = m$m$被选中的概率 ×$\times$ m$m$之后的元素都不被选中的概率。
p(m)=1m×(mm+1×m+1m+2×...×n2n1×n1n)=1n$p(m) = \frac {1}{m} \times (\frac {m}{m+1} \times \frac {m+1}{m+2} \times ...\times \frac {n-2}{n-1} \times \frac {n-1}{n}) = \frac {1}{n}$

## 代码

#### 我的代码

/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
Note that the head is guaranteed to be not null, so it contains at least one node. */
for(ListNode *cur = head; cur; cur = cur->next) {
size++;
}
}

/** Returns a random node's value. */
int getRandom() {
int random = rand() % size;
for (int i = 0; i < random; i++) {
cur = cur->next;
}
return cur->val;
}

private:
int size;
};

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

#### 参考代码

/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
Note that the head is guaranteed to be not null, so it contains at least one node. */

/** Returns a random node's value. */
int getRandom() {
for (int i = 2; cur; i++) {
// choos i with a probability of 1/i
if (rand() % i == 0)
random = cur->val;
cur = cur->next;
}
return random;
}

private:
};

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

## 总结

2.数据工程师必知算法：蓄水池抽样

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120