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

水塘抽样原理
总结:在取第n个数据的时候,我们生成一个0到1的随机数p,如果p小于1/n,保留第n个数。大于1/n,继续保留前面的数。直到数据流结束,返回此数

补充: c++ 标准库中的rand()函数。C++标准函数库提供一随机数生成器rand,返回0-RAND_MAX之间均匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始值)。
rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。 这样,如果你要产生0~10的10个整数,可以表达为: 
int N = rand()%11; 
     这样,N的值就是一个0~10的随机数,如果要产生1~10,则是这样: int N = 1+rand() % 10; 总结来说,可以表示为: 
     a + rand()%n   其中的a是起始值,n是整数的范围。 a + rand() % (b-a+1) 就表示 a~b之间的一个随机数

在每一个数的时候我们只要按照随机一个是否是i的倍数即可决定是否取当前数即可.
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
    Solution(ListNode* head) {
        p = head;
    }
    
    /** Returns a random node's value. */
    int getRandom() {
        ListNode *tem = p;  
        int val = p -> val;  
        for(int i = 1; tem; i++)  
        {  
            if(rand() % i == 0) val = tem->val;   // 如果产生的值为i,此时返回
            tem = tem -> next;  
        }  
        return val;  
    }  
    
private:  
    ListNode *p; 
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(head);
 * int param_1 = obj.getRandom();
 */

 

posted @ 2017-10-20 09:58  爱简单的Paul  阅读(161)  评论(0编辑  收藏  举报