zoukankan      html  css  js  c++  java
  • Linked List Random Node -- LeetCode

    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:

    1 // Init a singly linked list [1,2,3].
    2 ListNode head = new ListNode(1);
    3 head.next = new ListNode(2);
    4 head.next.next = new ListNode(3);
    5 Solution solution = new Solution(head);
    6 
    7 // getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
    8 solution.getRandom();

    思路:从n个数中选k个数,每个数被选中的几率是k/n的方法:

    将n个数的前k个数选出来,构成一个备选集合。然后从第k+1个数开始向后遍历直到第n个数。遍历第k+1个数时,我们用k/(k+1)的几率选中它,然后随机替换掉备选集合中的一个数。则此时对于备选集合中的每个数,不被替换掉的几率是 1 - P(第k+1个数被选中并替换掉该数) = 1 - k/(k+1) * 1/k = k/(k+1)。

    假设遍历到第i个数时,一个数留在备选集合中的概率是k/i。则对于第i+1个数,我们用k/(i+1)的概率选中它,并随机替换掉备选集合中的一个数,则对于备选集合中的每一个数,仍然留在集合中的概率是P(该数在上一次流了下来)(1-P(第i+1个数被选中并替换掉该数))= k/i * (1 - k/(i+1) * 1/k) = k/(i+1)。

    因此,当我们进行到第n个数时,该数进入备选集合的概率是k/n, 备选集合中其他的数留下的概率是k/n。最后备选集合中的数就是我们要随机选出的k个数,每个数被选出的几率是k/n。

    这个题里,让k等于1即可。因此备选集合中始终只有一个值,遍历第i个数时,用1/i的概率选中它并与备选值进行替换。最后的备选值就是随机选出的数,选取的概率为1/n。

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode* head;
    12     /** @param head The linked list's head.
    13         Note that the head is guaranteed to be not null, so it contains at least one node. */
    14     Solution(ListNode* head) {
    15         this->head = head;
    16     }
    17     
    18     /** Returns a random node's value. */
    19     int getRandom() {
    20         ListNode* res;
    21         int count = 1;
    22         for (ListNode* i = head; i != NULL; i = i->next, count++) {
    23             srand(time(NULL));
    24             int roll = rand() % count + 1; 
    25             if (roll == 1) res = i;
    26         }
    27         return res->val;
    28     }
    29 };
    30 
    31 /**
    32  * Your Solution object will be instantiated and called as such:
    33  * Solution obj = new Solution(head);
    34  * int param_1 = obj.getRandom();
    35  */
  • 相关阅读:
    链表--判断一个链表是否为回文结构
    矩阵--“之”字形打印矩阵
    二叉树——平衡二叉树,二叉搜索树,完全二叉树
    链表--反转单向和双向链表
    codeforces 490C. Hacking Cypher 解题报告
    codeforces 490B.Queue 解题报告
    BestCoder19 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告
    codeforces 488A. Giga Tower 解题报告
    codeforces 489C.Given Length and Sum of Digits... 解题报告
    codeforces 489B. BerSU Ball 解题报告
  • 原文地址:https://www.cnblogs.com/fenshen371/p/5798837.html
Copyright © 2011-2022 走看看