Given a singly linked list, return a random node ' s value from the linked list. Each node must has the same probability of being chosen.
Follow up:
What if the linked list was extremely large and its length is unknown? Could solve this efficiently without using extra space?
Example:
Init a singly linked list [I/b]. 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 has equal probability of returning.solution.getRandom ();
Gives a list, randomly returns a node.
Solution 1: First count the length of the list, then randomly generate a position based on the length, and then traverse from the beginning to this position. But if n is big, it's not going to work.
Solution 2: Reservoir sampling reservoir sampling is a series of random algorithms that are designed to select K samples from a set of n items, where n is a large or unknown quantity, especially for cases where all n items cannot be stored in memory.
Java:
public class Solution { ListNode head; Random random; Public solution (ListNode h) { head = h; Random = new Random (); } public int getrandom () { ListNode c = head; int r = c.val; for (int i=1;c.next! = null;i++) { c = c.next; if (Random.nextint (i + 1) = = i) R = c.val; } return r; }}
Python:
From random Import Randintclass solution (object): def __init__ (self, head): "" " @param head the linked list ' S head. Note that the head was guanranteed to was not null and so it contains at least one node. : Type Head:listnode "" " S Elf.__head = Head # Proof of Reservoir sampling: # https://discuss.leetcode.com/topic/53753/ Brief-explanation-for-reservoir-sampling def getrandom (self): "" " Returns a random node ' s value. : Rtype:int "" " Reservoir =-1 curr, n = self.__head, 0 while curr: reservoir = Curr.val if Randi NT (1, n+1) = = 1 Else reservoir curr, n = curr.next, n+1 return Reservoir
C + +: 1
Class Solution {public: /** @param head the linked list ' s head. Note that the head was guanranteed to was not null and 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;};
C + +: 2
Class Solution {public: /** @param head the linked list ' s head. Note that the head was guanranteed to was not null and 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;};
Similar topics:
398. Random Pick Index
[Leetcode] 382. Linked list random node linked list