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.node
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?dom
Example:this
// 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();
解法: spa
因爲沒法肯定鏈表的長度,或者鏈表的長度很長,所以須要採用水塘抽樣算法。因爲限定了head必定存在,因此咱們先讓返回值res等於head的節點值,而後讓curr指向head的下一個節點,定義一個變量count,初始化爲1,若curr不爲空咱們開始循環,咱們在[0, count)中取一個隨機數,若是取出來0,那麼咱們更新res爲當前的curr的節點值,而後此時count自增一,curr指向其下一個位置,這裏其實至關於咱們維護了一個大小爲1的水塘,而後咱們隨機數生成爲0的話,咱們交換水塘中的值和當前遍歷到底值,這樣能夠保證每一個數字的機率相等,參見代碼以下:code
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { private ListNode head; /** @param head The linked list's head. Note that the head is guaranteed to be not null, so it contains at least one node. */ public Solution(ListNode head) { this.head = head; } /** Returns a random node's value. */ public int getRandom() { int count = 1; int res = head.val; ListNode curr = head.next; while (curr != null) { if (new Random().nextInt(++count) == 0) { res = curr.val; } curr = curr.next; } return res; } } /** * Your Solution object will be instantiated and called as such: * Solution obj = new Solution(head); * int param_1 = obj.getRandom(); */