最近刷Leetcode,刷题过程持续更新。
leetcode 382题:
[LeetCode] 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();
这题自己解决的时候就是想获取链表长度,然后随机一个数值,获取该数值指向的节点的值即可;长度未知的情况查询后得知使用鱼塘抽样
有篇讲解的不错的博客可以看一下。
leetcode参考的博客地址为http://www.cnblogs.com/grandyang/p/5759926.html
粘贴一下代码:
解法一
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) {
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;
}
private:
int len;
ListNode *head;
};
解法二:鱼塘算法
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) {
this->head = head;
}
/** Returns a random node's value. */
int getRandom() {
int res = head->val, i = 2;
ListNode *cur = head->next;
while (cur) {
int j = rand() % i;
if (j == 0) res = cur->val;
++i;
cur = cur->next;
}
return res;
}
private:
ListNode *head;
};