题目
解法1:
第一种方法就是最容易想到的,求出链表的长度,然后从这个长度区间里去一个随机位置返回
python的代码如下:
class Solution:
def __init__(self, head: ListNode):
"""
@param head The linked list's head.
Note that the head is guaranteed to be not null, so it contains at least one node.
"""
self._len = 0
self.head = head
while head.next:
head = head.next
self._len += 1
def getRandom(self) -> int:
"""
Returns a random node's value.
"""
chose = random.randint(0,self._len)
head = self.head
while chose:
head = head.next
chose -= 1
return head.val
解法2:水库取样
这道题有个follow up,假设我们无法知道链表的长度,这个时候标准的解法应该是水库取样,具体如下:
遍历一次链表,在遍历到第 m 个节点时,有 1 m 的概率选择这个节点覆盖掉之前的节点选择。
想要详细了解水库取样的可以看这个博客
这边用C++写。C++的rand()函数用法是这样的。rand%i会产生0-(i-1)中的一个随机数,所以每个数被产生的概率就是1/i。所以取rand()%i0或者1都可以,代码如下:
class Solution {
ListNode* _head;
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) {
_head = head;
}
/** Returns a random node's value. */
int getRandom() {
int ans = _head->val;
ListNode *node = _head->next;
int i=2;
while(node){
if (rand()%i==0){
ans = node->val;
}
i++;
node = node->next;
}
return ans;
}
};
参考链接:https://github.com/changgyhub/notes/blob/master/leetcode/leetcode-601-650.md