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 = ;
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 = ;
ListNode *cur = head->next;
while (cur) {
int j = rand() % i;
if (j == ) 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 题目讲解汇总(持续更新中...)

[LeetCode] Linked List Random Node 链表随机节点的更多相关文章

  1. [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 t ...

  2. 382 Linked List Random Node 链表随机节点

    给定一个单链表,随机选择链表的一个节点,并返回相应的节点值.保证每个节点被选的概率一样.进阶:如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现?示例:// 初始化一个单链表 ...

  3. LeetCode: Linked List Random Node

    这题参照http://blog.jobbole.com/42550/ 用的蓄水池算法,即更改ans的概率为1/(当前length) /** * Definition for singly-linked ...

  4. Java实现 LeetCode 382 链表随机节点

    382. 链表随机节点 给定一个单链表,随机选择链表的一个节点,并返回相应的节点值.保证每个节点被选的概率一样. 进阶: 如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现? ...

  5. [Swift]LeetCode382. 链表随机节点 | Linked List Random Node

    Given a singly linked list, return a random node's value from the linked list. Each node must have t ...

  6. 【LeetCode】382. Linked List Random Node 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数组保存再随机选择 蓄水池抽样 日期 题目地址:ht ...

  7. [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 t ...

  8. Linked List Random Node -- LeetCode

    Given a singly linked list, return a random node's value from the linked list. Each node must have t ...

  9. Leetcode 382. Linked List Random Node

    本题可以用reservoir sampling来解决不明list长度的情况下平均概率选择元素的问题. 假设在[x_1,...,x_n]只选一个元素,要求每个元素被选中的概率都是1/n,但是n未知. 其 ...

随机推荐

  1. Cesium原理篇:GroundPrimitive

    今天来看看GroundPrimitive,选择GroundPrimitive有三个目的:1 了解GroundPrimitive和Primitive的区别和关系 2 createGeometry的特殊处 ...

  2. TeamCity : .NET Core 插件

    笔者在<TeamCity : 配置 Build 过程>一文中提到 "TeamCity 内置支持几乎所有的 build 类型".在当今这个软件语言和各种框架飞速发展的时代 ...

  3. angularjs和ajax的结合使用 (二)

    今天我们来继续丰富上次的例子.我们来搞些 稍微复杂点的应用. 首先我们来加一个全选 的功能. 上一篇的例子里我们看到 分页时载入的是我们通过linq 查询自定义列 然后构建的匿名类 .使用这种EF框架 ...

  4. dicom网络通讯入门(2)

    第二篇,前面都是闲扯 其实正文现在才开始,这次是把压箱底的东西都拿出来了. 首先我们今天要干的事是实现一个echo响应测试工具 也就是echo 的scu,不是实现打印作业管理么.同学我告诉你还早着呢. ...

  5. 控制反转、依赖注入、Unity容器

    控制反转原则 依赖注入 Install-Package Unity:https://www.nuget.org/packages/Unity/ Github:https://github.com/un ...

  6. agsXMPP

    agsXMPP使用 agsXMPP中的例子已经有注册.登录.添加好友.接收好友添加请求.发送消息.接收消息等功能. 修改用户密码 登录后可用以下方法修改密码 IQ iq = new IQ(IqType ...

  7. python中的TypeError错误解决办法

    新手在学习python时候,会遇到很多的坑,下面来具体说说其中一个. 在使用python编写面向对象的程序时,新手可能遇到TypeError: this constructor takes no ar ...

  8. ASP.NET CORE配置信息

    做个笔记,原文链接 除了应用 IOptions<T> .Value的方式对配置信息进行全局注册外可以应用的另一个微软给出的组件,需要依赖两个包 Microsoft.Extensions.C ...

  9. nw.js自定义最小化图标的click事件

    选择frameless时,最小化和关闭按钮的点击事件需要自己来做,办法是: /* * 下面两个模块一定要引入到js文件中 */ var gui = require('nw.gui'); var win ...

  10. 使用CSS3制作导航条和毛玻璃效果

    导航条对于每一个Web前端攻城狮来说并不陌生,但是毛玻璃可能会相对陌生一些.简单的说,毛玻璃其实就是让图片或者背景使用相应的方法进行模糊处理.这种效果对用户来说是十分具有视觉冲击力的. 本次分享的主题 ...