LeetCode 382. Linked List Random Node

简介: 给定一个单链表,随机选择链表的一个节点,并返回相应的节点值。保证每个节点被选的概率一样。

v2-f71219f24da2d6364f6c6c6c44c6b332_1440w.jpg

Description



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


描述



给定一个单链表,随机选择链表的一个节点,并返回相应的节点值。保证每个节点被选的概率一样。


进阶:

如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现?


示例:


// 初始化一个单链表 [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()方法应随机返回1,2,3中的一个,保证每个元素被返回的概率相等。
solution.getRandom();
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-random-node
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路


  • 这道题的理论证明参见维基百科
  • 首先让数字 num 为链表中的头节点的值,count 置为 1;每次往后走一个节点的时候,生成一个 1 到 count 的随机数,如果生成的随机数能够整除 count,就把 num 和当前节点的值替换(条件不已经必须设置为整除 count,设为 0或者其他概率是 1/count 的数都可以),否则不替换;最后返回 num。


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-07-30 07:41:23
# @Last Modified by:   何睿
# @Last Modified time: 2019-07-30 07:46:44
import random
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def __init__(self, head: ListNode):
        """
        @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node.
        """
        self.head = head
    def getRandom(self) -> int:
        """
        Returns a random node's value.
        """
        head = self.head
        num = head.val
        node = head.next
        count = 1
        while node:
            count += 1
            if random.randint(1, count) % count == 0:
                num = node.val
            node = node.next
        return num

源代码文件在 这里


目录
相关文章
|
6月前
|
Java
Leetcode 114. Flatten Binary Tree to Linked List
思路也很简单,先把root的左子树(如有)变成单链表 leftlinkedlist,把root的右子树(如有)变成单链表 rightlinkedlist,再把root的右节点变成leftlikedlist,再把rightlinkedlist接到leftlinkedlist后面,代码如下。
20 1
|
6月前
|
C++
Leetcode Copy List with Random Pointer(面试题推荐)
给大家推荐一道leetcode上的面试题,这道题的具体讲解在《剑指offer》的P149页有思路讲解,如果你手头有这本书,建议翻阅。
26 0
|
2月前
|
设计模式 测试技术
在实现链表的代码中,为什么要使用`Node`类而不是直接在`LinkedList`类中定义节点?
在实现链表的代码中,为什么要使用`Node`类而不是直接在`LinkedList`类中定义节点?
21 1
LeetCode 237. 删除链表中的节点 Delete Node in a Linked List
LeetCode 237. 删除链表中的节点 Delete Node in a Linked List
LeetCode Contest 178-1367. 二叉树中的列表 Linked List in Binary Tree
LeetCode Contest 178-1367. 二叉树中的列表 Linked List in Binary Tree
|
Python
Leetcode-Easy 876. Middle of the Linked List
Leetcode-Easy 876. Middle of the Linked List
70 0
Leetcode-Easy 876. Middle of the Linked List
LeetCode 138:复制带随机指针的链表 Copy List with Random Pointer
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的深拷贝。 A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
819 0
LeetCode 430:扁平化多级双向链表 Flatten a Multilevel Doubly Linked List
您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表。这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。 扁平化列表,使所有结点出现在单级双链表中。
829 0
|
算法 Java Python
LeetCode 328:奇偶链表 Odd Even Linked List
​给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。 请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
671 0
LeetCode 142:环形链表 II Linked List Cycle II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
921 0