[leetcode] 382. Linked List Random Node 解题报告
2016-08-12 04:45
330 查看
题目链接: https://leetcode.com/problems/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:
思路: 一般的来说, 可以先计算出长度, 然后随机一个在长度范围内的值, 走到那里将值返回即可. 但是如果长度无限大, 就无法计算长度了, 这种情况下成为一个水池抽样的算法, 其原理为一个个的对元素取样, 在遍历到每个元素的时候可以有个概率选取, 或者不选取. 因为是随机选取一个数, 所以相当于水池的容量是1. 相对简单一些.
那么如何确保对于每个元素都有相等的概率呢? 这里用到了概率论的知识, 在遍历到第i个数时设置选取这个数的概率为1/i, 然后来证明一下每个数被选到的概率: 对于第一个数其被选择的概率为1/1*(1-1/2)*(1-1/3)*(1-1/4)*...*(1-1/n) = 1/n, 其中(1-1/n)的意思是不选择n的概率, 也就是选择1的概率乘以不选择其他数的概率. 对于任意一个数i来说, 其被选择的概率为1/i*(1-1/(i+1))*...*(1-1/n), 所以在每一个数的时候我们只要按照随机一个是否是i的倍数即可决定是否取当前数即可.
代码如下:
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. 相对简单一些.
那么如何确保对于每个元素都有相等的概率呢? 这里用到了概率论的知识, 在遍历到第i个数时设置选取这个数的概率为1/i, 然后来证明一下每个数被选到的概率: 对于第一个数其被选择的概率为1/1*(1-1/2)*(1-1/3)*(1-1/4)*...*(1-1/n) = 1/n, 其中(1-1/n)的意思是不选择n的概率, 也就是选择1的概率乘以不选择其他数的概率. 对于任意一个数i来说, 其被选择的概率为1/i*(1-1/(i+1))*...*(1-1/n), 所以在每一个数的时候我们只要按照随机一个是否是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 guanranteed 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; 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(); */参考: http://www.faceye.net/search/99720.html
相关文章推荐
- [Leetcode] 642. Design Search Autocomplete System 解题报告
- [Leetcode] 116. Populating Next Right Pointers in Each Node 解题报告
- [Leetcode] 314. Binary Tree Vertical Order Traversal 解题报告
- [leetcode]126. Word LadderII@Java解题报告
- [LeetCode] 501. Find Mode in Binary Search Tree 解题报告
- 【LeetCode】628. Maximum Product of Three Numbers 解题报告
- [leetcode]151. Reverse Words in a String@Java解题报告
- LeetCode: Generate Parentheses 解题报告
- [Leetcode] 774. Minimize Max Distance to Gas Station 解题报告
- Leetcode 102. Binary Tree Level Order Traversal 二叉树按层遍历 解题报告
- [Leetcode] 668. Kth Smallest Number in Multiplication Table 解题报告
- [leetcode] 392. Is Subsequence 解题报告
- LeetCode Longest Valid Parentheses 解题报告
- 【LeetCode】Convert Sorted List to Binary Search Tree 解题报告
- [LeetCode]Surrounded Regions,解题报告
- [LeetCode] 424. Longest Repeating Character Replacement 解题报告
- Leetcode 76-MinimumWindowSubstring 解题报告
- LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
- LeetCode解题报告 383. Ransom Note [easy]
- LeetCode: Max Points on a Line 解题报告