382&398. Linked List Random Node,Random Pick Index

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?

这道题如果不考虑follow up会很简单,遍历一遍链表,把值存到一个List里,取的时候随机出一个下标来取就好。

public class Solution {

    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
    private ArrayList<Integer> a=new ArrayList<Integer>(); 
    private int b = 0;
    public Solution(ListNode head) {
        while (head!=null) {
            a.add(head.val);
            head = head.next;
            b++;
        }
    }
    
    /** Returns a random node's value. */
    public int getRandom() {
        int index = (int)(Math.random()*(b));
        int res = a.get(index);
        return res;
    }
}

但是,如果在长度未知的情况下进行随机,这个就不行了,比如链表是随时变化的,就不能用这样的方法。
这是著名的蓄水池问题,在未知长度的数据中随机出k个数据。
比如,我们要从1,2,3中随机选出一个。
假设我们的结果是res
我们从头开始遍历这个链表:
遍历到第一个时,我们选1的概率是1,res=1
遍历到第二个时,我们选2的概率应该是1/2,1的概率也应该是是1/2。我们以1/2的概率执行res=2
遍历到第三个时,我们选每个数的概率是1/3,我们以1/3的概率执行res=3
此时,res=1,2,3的概率分别是1/2(1-1/3),1/2(1-1/3),1/3。即1/3,1/3,1/3
所以:

public class Solution {
    ListNode head;
    Random random;
    public Solution(ListNode head) {
        this.head = head;
        random = new Random();
    }
    
    /** Returns a random node's value. */
    public int getRandom() {
        int count = 0;
        int result = -1;
        ListNode dummyhead = head;
        while(dummyhead != null) {
            if(random.nextInt(++count) == 0) {
                result = dummyhead.val;
            }
            dummyhead = dummyhead.next;
        }
        return result;
    }
}

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

这个和上面的问题几乎一样的,就是这次选的时候只在特定的值中选

public class Solution {
    int [] data;
    Random random;
    public Solution(int[] nums) {
        data = nums;
        random = new Random();
    }
    
    public int pick(int target) {
        int count = 0;
        int result = -1;
        for(int i = 0;i<data.length;i++) {
            if (data[i]==target) {
                 if(random.nextInt(++count) == 0) {
                    result = i;
                }
            }
        }
        return result;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,357评论 0 33
  • Single Linked List 相比较另一个基本的数据结构array,linked list有几个优势:尺寸...
    dol_re_mi阅读 12,534评论 0 3
  • 太忙,以至于懒得写标题。 今早7点前起来,很清醒。昨晚状态很差,逻辑40%正确率,猜都没猜对。 看了解析,依然比较...
    彭黎Jessie阅读 1,630评论 0 0
  • 《造府普洱》不止有普洱茶文化 传播:中国传统文化|茶道|文学|养生|视觉 惊蛰节,春雷响,万物长,茶蜕壳 春风如林...
    造府秋香阅读 3,783评论 0 1
  • 一、怎样讲好一个故事? 好故事的四大要素:曲折的情节(plot)、丰富的情感(emotion)、生动的细节(det...
    第五因阅读 7,951评论 0 51

友情链接更多精彩内容