美文网首页我爱编程
382. Linked List Random Node

382. Linked List Random Node

作者: Nancyberry | 来源:发表于2018-05-27 05:29 被阅读0次

    Description

    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();

    Solution

    Cache + nextInt, constructor O(n), getRandom O(1), S(n)

    将LinkedList的所有value按顺序添加到cache中,getRandom时只需对cache.size()进行采样,返回对应的值即可。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        private List<Integer> cache;
        private Random random;
        /** @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) {
            cache = new ArrayList<>();
            random = new Random();
            
            while (head != null) {
                cache.add(head.val);
                head = head.next;
            }
        }
        
        /** Returns a random node's value. */
        public int getRandom() {
            return cache.get(random.nextInt(cache.size()));
        }
    }
    
    /**
     * Your Solution object will be instantiated and called as such:
     * Solution obj = new Solution(head);
     * int param_1 = obj.getRandom();
     */
    

    Followup: Reservoir sampling, constructor O(1), getRandom O(n), S(1)

    经典的蓄水池抽样算法,从n(非常大)个元素中随机选择k个元素,对应到这道题k = 1。
    优点是不需要将LinkedList全部载入内存,可以以stream的形式更新random。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        private ListNode head;
        private Random random;
        /** @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;
            random = new Random();
        }
        
        /** Returns a random node's value. */
        public int getRandom() {
            int val = head.val;
            ListNode curr = head.next;
            
            for (int i = 1; curr != null; ++i, curr = curr.next) {
                if (random.nextInt(i + 1) == 0) {   // random between [0, i]
                    val = curr.val;
                }
            }
            
            return val;
        }
    }
    
    /**
     * Your Solution object will be instantiated and called as such:
     * Solution obj = new Solution(head);
     * int param_1 = obj.getRandom();
     */
    

    相关文章

      网友评论

        本文标题:382. Linked List Random Node

        本文链接:https://www.haomeiwen.com/subject/qdnvjftx.html