0382. Linked List Random Node

382. Linked List Random Node #

题目 #

给定单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点被选中的概率一样。

考虑处理以下情形:

  • 链表非常大且长度未知
  • 使用O(1)的额外空间复杂度

思路 #

使用 蓄水池抽样算法O(n)的时间复杂度和O(1)的空间复杂度解决此问题。

代码 #

public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

class Solution {
    private Random rand;
    private ListNode sentinel;
    
    public Solution(ListNode head) {
        this.rand = new Random();
        this.sentinel = new ListNode(-1, head);
    }
    
    public int getRandom() {
        ListNode ptr = this.sentinel;
        int size = 0, result = -1;
        while (ptr.next != null) {
            ptr = ptr.next;
            size += 1;
            if (this.rand.nextInt(0, size) == 0) result = ptr.val;
        }
        return result;
    }
}

致谢 #