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();
蓄水池算法,要是我肯定是想不出来的,所以不会做,网上看到的代码。
代码如下:
/*
class ListNode
{
int val;
ListNode next;
ListNode(int x) { val = x; }
}
*/
/*
* 这道题用到的就是这个蓄水池算法。看代码的时候就简单多了。
*/
class Solution
{
ListNode head;
public Solution(ListNode head)
{
this.head = head;
}
public int getRandom()
{
Random random = new Random();
int result = head.val;
ListNode currNode = head;
for(int i=1; currNode.next!=null; i++)
{
currNode = currNode.next;
if((random.nextInt(i + 1)) == i)
{
result = currNode.val;
}
}
return result;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(head);
* int param_1 = obj.getRandom();
*/
下面是C++做法,
这道题给了我们一个链表,让我们随机返回一个节点,那么最直接的方法就是先统计出链表的长度,然后根据长度随机生成一个位置,然后从开头遍历到这个位置即可,
可以和这道题leetcode 384. Shuffle an Array 数组随机洗牌一起学习
代码如下:
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
using namespace std;
/*
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
*/
class Solution
{
public:
int len;
ListNode *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. */
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;
}
};