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

进阶:
如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现?

示例:

// 初始化一个单链表 [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()方法应随机返回1,2,3中的一个,保证每个元素被返回的概率相等。
solution.getRandom();
Related Topics
  • 水塘抽样
  • 链表
  • 数学
  • 随机化

  • 👍 151
  • 👎 0
  • 题解

    简单啊,,,随机么。直接存成数组,然后一个

    Math.random()

    出来了

    class Solution2 {
    
        List<ListNode> list;
        /** @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 Solution2(ListNode head) {
            list = new ArrayList<>();
            while (head!=null){
                list.add(head);
                head = head.next;
            }
        }
    
        /** Returns a random node's value. */
        public int getRandom() {
            int random = (int)(Math.random() * list.size());
            return list.get(random).val;
        }
    }

    进阶。不用总长度怎么取随机,最近好像遇到好几次了,特地花了点时间去仔细理解了下水塘抽样随机算法。本题题解如下

    class Solution {
    
        ListNode head;
        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() {
            ListNode node = head;
            int count = 1;
            int val = node.val;
            while (node!=null){
                if (random.nextInt(count) == 1){
                    val =node.val;
                }
                count++;
                node = node.next;
            }
            return val;
        }
    }