382. Linked List Random Node 蓄水池抽样法
来源:互联网 发布:2017最新微信站街软件 编辑:程序博客网 时间:2024/06/06 08:03
382. Linked List Random Node
题目链接
题意
给你一个(很长)的链表,你需要从中随机地取出一个结点的值,并且保证取每个结点的概率是相同的。
解法
蓄水池抽样法(resevoir sampling)的特例。
在这种情况下,蓄水池抽样法总是选择第一个对象,以1/2的概率选择第二个,以1/3的概率选择第三个,以此类推,以1/m的概率选择第m个对象。当该过程结束时,每一个对象具有相同的选中概率,即1/n,证明如下。
证明:第m个对象最终被选中的概率P=选择m的概率*其后面所有对象不被选择的概率,即
P=1m×(mm+1×m+1m+2×…n−1n)=1n
代码
/** * 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) { this->head = head; } /** Returns a random node's value. */ int getRandom() { int ans = head->val, i = 2; ListNode* cur = head->next; while(cur) { int j = rand() % i; if(!j) ans = cur->val; i++; cur = cur->next; } return ans; }private: ListNode* head = nullptr;};/** * Your Solution object will be instantiated and called as such: * Solution obj = new Solution(head); * int param_1 = obj.getRandom(); */
我还看到了一种解法
/** * 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):cur(head) { } /** Returns a random node's value. */ int getRandom() { int val=cur->val; ListNode *temp=cur; for(int i=0;temp!=nullptr;temp=temp->next,++i) { uniform_int_distribution<unsigned> u(0,i); default_random_engine e(rand());//真正随机的种子 unsigned int m=u(e); if(m<1) { val=temp->val; } } return val; }private: ListNode *cur;};/** * Your Solution object will be instantiated and called as such: * Solution obj = new Solution(head); * int param_1 = obj.getRandom(); */
蓄水池抽样法
真正的蓄水池抽样问题是,即从一个包含n个对象的列表S中随机选取k个对象,n为一个非常大或者不知道的值。通常情况下,n是一个非常大的值,大到无法一次性把所有列表S中的对象都放到内存中。
我们先把读到的前k个对象放入“水库”,对于第k+1个对象开始,以
证明:第m个对象被选中的概率=选择m的概率(其后元素不被选择的概率+其后元素被选择的概率不替换第m个对象的概率),即
P=km×[(m+1−km+1+km+1×k−1k)×(m+2−km+2+km+2×k−1k×⋯×(n−kn+kn×k−1k)]=km×mn=kn
#include <iostream> #include <cstdlib> #include <ctime> #include <vector> using namespace std; typedef vector<int> vi; typedef typename vi::iterator it; typedef typename vi::const_iterator cit; // generate a random number between i and k, // both i and k are inclusive. int randint(int i, int k) { if(i > k) { int t = i; i = k; k = t; // swap } int ret = i + rand() % (k - i + 1); return ret; } // take m samples to result from input of n items. bool reservoir_sampling(const vi &input, vi &result, int m) { srand(time(NULL)); if(input.size() < m) return false; result.resize(m); cit it = input.begin(); for(int i = 0; i != m; i++) result[i] = *it++; for(int i = m; it != input.end(); i++, it++) { int j = randint(0, i); if (j < m) result[j] = *it; } return true; } int main() { const int n = 100; const int m = 10; vi input(n), result(m); for(int i = 0; i < n; i++) input[i] = i; if(reservoir_sampling(input, result, m)) for (int i = 0; i < m; ++i) cout << result[i] << " "; cout << endl; return 0; }
阅读全文
0 0
- 382. Linked List Random Node 蓄水池抽样法
- 382. Linked List Random Node (蓄水池抽样,java)
- Leetcode Linked List Random Node C++(蓄水池抽样算法)
- LeetCode:382 Linked List Random Node蓄水池抽样算法
- 蓄水池抽样算法 LeetCode382. Linked List Random Node
- LeetCode:382. Linked List Random Node(蓄水池抽样算法C++)
- 蓄水池算法382. Linked List Random Node
- 382.[LeetCode]Linked List Random Node(蓄水池算法)
- leetcode 382. Linked List Random Node 蓄水池算法
- Leetcode 382. Linked List Random Node 以及 水塘抽样算法
- 398. Random Pick Index &&382. Linked List Random Node 蓄水池原理
- LeetCode 382 Linked List Random Node (蓄水池算法 推荐)
- 382. Linked List Random Node
- 382. Linked List Random Node
- 382. Linked List Random Node
- 382. Linked List Random Node
- 382. Linked List Random Node
- 382. Linked List Random Node
- Android之Notification抽屉通知详解
- BST, 二叉树
- 【Java多线程】类锁和对象锁
- CSRF跨站请求伪造
- 【Java多线程】对象锁的同步和异步
- 382. Linked List Random Node 蓄水池抽样法
- Java-Java I/O流解读之Object Serialization and Object Streams
- 随写
- 近期情绪管理有感
- 1.1DOS常用命令及Java环境相关配置问题
- 个人学习第三章节:常见脚本
- linux内存管理之slab数据结构三巨头
- caioj.1042 背包搜索
- 【Leetcode】【python】Search in Rotated Sorted Array/Search in Rotated Sorted Array II