398.随机数索引

 

  • 方法一:哈希表

用哈希表map记录nums[i]的所有索引下标,pick时,取出map对应的下标列表,随机选择其中一个下标并返回。

  复杂度:时间复杂度:O(N);空间复杂度:O(N);

  • 方法二:水塘抽样

  如果数组以文件形式存储,且文件大小远超内存大小,我们无法通过读文件,将所有下标保存在内存中,因此需要找到一种空间复杂度更低的算法。

  我们可以设计如下算法实现pick操作:

  遍历nums,当我们第一次遇到值为target的元素时,随机选择区间[0, i)的一个整数,如果其等于0,则将该返回值置为该元素的下标,否则返回值不变。

  设nums中有k个值为target的元素,该算法会保证这k个元素的下标成为返回值的概率均为1/k,证明如下:

  

 

 

class Solution {
    int[] nums;
    Random random;

    public Solution(int[] nums) {
        this.nums = nums;
        random = new Random();
    }

    public int pick(int target) {
        int ans = 0;
        for (int i = 0, cnt = 0; i < nums.length; ++i) {
            if (nums[i] == target) {
                ++cnt; // 第 cnt 次遇到 target
                if (random.nextInt(cnt) == 0) {
                    ans = i;
                }
            }
        }
        return ans;
    }
}

复杂度:时间复杂度:初始化为O(1),pick为O(N);空间复杂度:O(1);

posted on 2022-04-25 10:34  Kenina  阅读(58)  评论(0)    收藏  举报

导航