zoukankan      html  css  js  c++  java
  • [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.

    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:先统计出链表的长度,然后根据长度随机生成一个位置,然后从开头遍历到这个位置。但如果n很大就不好处理了。

    解法2: 水塘抽样 Reservoir sampling,是一系列的随机算法,其目的在于从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数量,尤其适用于不能把所有n个项目都存放到内存的情况。

    Java:

    public class Solution {
        
        ListNode head;
        Random random;
        
        public Solution(ListNode h) {
            head = h;       
            random = new Random();        
        }
        
        public int getRandom() {
            
            ListNode c = head;
            int r = c.val;
            for(int i=1;c.next != null;i++){
                
                c = c.next;
                if(random.nextInt(i + 1) == i) r = c.val;                        
            }
            
            return r;
        }
    } 

    Python:

    from random import randint
    
    class Solution(object):
    
        def __init__(self, head):
            """
            @param head The linked list's head. Note that the head is guanranteed to be not null, so it contains at least one node.
            :type head: ListNode
            """
            self.__head = head
    
    
        # Proof of Reservoir Sampling:
        # https://discuss.leetcode.com/topic/53753/brief-explanation-for-reservoir-sampling
        def getRandom(self):
            """
            Returns a random node's value.
            :rtype: int
            """
            reservoir = -1
            curr, n = self.__head, 0
            while curr:
                reservoir = curr.val if randint(1, n+1) == 1 else reservoir
                curr, n = curr.next, n+1
            return reservoir
    

    C++: 1

    class Solution {
    public:
        /** @param head The linked list's head. Note that the head is guanranteed to be not null, so it contains at least one node. */
        Solution(ListNode* head) {
            len = 0;
            ListNode *cur = head;
            this->head = head;
            while (cur) {
                ++len;
                cur = cur->next;
            }
        }
        
        /** Returns a random node's value. */
        int getRandom() {
            int t = rand() % len;
            ListNode *cur = head;
            while (t) {
                --t;
                cur = cur->next;
            }
            return cur->val;
        }
    private:
        int len;
        ListNode *head;
    };

    C++: 2

    class Solution {
    public:
        /** @param head The linked list's head. Note that the head is guanranteed to be not null, so it contains at least one node. */
        Solution(ListNode* head) {
            this->head = head;
        }
        
        /** Returns a random node's value. */
        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;
    };
    

      

    类似题目:

    398. Random Pick Index

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
    便携版WinSCP在命令行下同步文件夹
    ffmpeg (ffprobe)分析文件关键帧时间点
    sqlite删除数据或者表后,回收数据库文件大小
    ubuntu 20.04下 freeswitch 配合 fail2ban 防恶意访问
    ffmpeg使用nvenc编码的结论记录
    PC版跑跑卡丁车 故事模式 亚瑟传说章节 卡美洛庆典 2阶段 心灵之眼 攻略
    There was an error loading or playing the video
    Nvidia RTX Voice 启动报错修复方法
    火狐浏览器 关闭跨域限制
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9739200.html
Copyright © 2011-2022 走看看