Reservoir Samplings

Linked List Random Node

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

思路
蓄水池原理

  1. 从头到尾遍历链表
  2. 在遍历1~i个结点时,直接放进结果集
  3. 遍历到第k(k > i)个结点时,以i/k的概率决定是否将结点i放进结果集。如果不放,直接忽略。如果放,就从结果集的i个结点中随机取出一个,替换为结点k
  4. 重复3,一直到尾节点。
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    ListNode head = null;

    /** @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() {
        ListNode result = this.head;
        ListNode curNode = this.head;
        Random random = new Random();
        
        for (int i = 1; curNode != null; i++) {
            if (random.nextInt(i) == i - 1) {
                result = curNode;
            }
            curNode = curNode.next;
        }
        return result.val;
    }
}
/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(head);
 * int param_1 = obj.getRandom();
 */

Random Pick Index

Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array.

Note:
The array size can be very large. Solution that uses too much extra space will not pass the judge.

Example:

int[] nums = new int[] {1,2,3,3,3};
Solution solution = new Solution(nums);

// pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
solution.pick(3);

// pick(1) should return 0. Since in the array only nums[0] is equal to 1.
solution.pick(1);

思路
Use random to ensure equal possibility, key point is save extra space.

  1. Create arraylist to store all index of target, and count total.
  2. Then use random from [0,total), to equally pick any element in the array.

Complexity: O(N)time O(m)space - # of target in nuts

class Solution {
    private int[] nums;

    public Solution(int[] nums) {
        this.nums = nums;
    }
    
    public int pick(int target) {
        List<Integer> list = new ArrayList<Integer>();
        int count = 0;
        int result = -1;
        
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == target) {
                count++;
                list.add(i);
            }
        }
        
        Random random = new Random();
        result = list.get(random.nextInt(count));
        return result;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int param_1 = obj.pick(target);
 */
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,774评论 0 33
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,916评论 0 23
  • 投资风险难自持 输赢参半未可知 钱去财往平常事 卷土重来犟女子
    红色阳光阅读 455评论 0 1
  • (5) “你还是什么都不说吗?”丁仁语气严厉。 李博低着头,默不作声。 “这个你总认识吧?”李博看到丁...
    紫蘇卡卡阅读 240评论 0 1
  • 经历了一些事情,好的,坏的,成功了,会激动,失败了,会痛苦,迷茫,有时候想的很多,想的头疼,不说话,会压抑,说多了...
    徐伟_快乐505阅读 362评论 0 0