382. 链表随机节点Normal水塘抽样算法
Posted pre_eminent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了382. 链表随机节点Normal水塘抽样算法相关的知识,希望对你有一定的参考价值。
题目:
给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。
每个节点 被选中的概率一样 。
实现 Solution 类:
Solution(ListNode head) 使用整数数组初始化对象。
int getRandom() 从链表中随机选择一个节点并返回该节点的值。
链表中所有节点被选中的概率相等。
示例:
输入
["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"]
[[[1, 2, 3]], [], [], [], [], []]
输出
[null, 1, 3, 2, 2, 3]
解释
Solution solution = new Solution([1, 2, 3]);
solution.getRandom(); // 返回 1
solution.getRandom(); // 返回 3
solution.getRandom(); // 返回 2
solution.getRandom(); // 返回 2
solution.getRandom(); // 返回 3
// getRandom() 方法应随机返回 1、2、3中的一个,每个元素被返回的概率相等。
提示:
链表中的节点数在范围 [1, 10^4] 内
-10^4 <= Node.val <= 10^4
至多调用 getRandom 方法 10^4 次
进阶:
如果链表非常大且长度未知,该怎么处理?
你能否在不使用额外空间的情况下解决此问题?
思路:
一轮遍历
生成随机数,
如果概率是1/i就替换
解答:
/**
* Definition for singly-linked list.
* function ListNode(val, next)
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
*
*/
/**
* @param ListNode head
*/
var Solution = function(head)
// 构造函数保留头节点
this.head = head;
;
/**
* @return number
*/
Solution.prototype.getRandom = function()
let i = 1;
let res = 0;
for(let node = this.head;node !== null;node = node.next)
// 如果是1/i的概率,就替换结果
// [0, 1)
let r = Math.random(1);
let p = Math.floor(r * i);
if(p === 0)
res = node.val;
i++;
return res;
;
/**
* Your Solution object will be instantiated and called as such:
* var obj = new Solution(head)
* var param_1 = obj.getRandom()
*/
以上是关于382. 链表随机节点Normal水塘抽样算法的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Algorithm 382. 链表随机节点
LeetCode Algorithm 382. 链表随机节点
LeetCode 1716. 计算力扣银行的钱 / 382. 链表随机节点(蓄水池抽样) / 1220. 统计元音字母序列的数目(动规,矩阵快速幂)