🌕🌗 398. 随机数索引

吞佛童子2022年10月10日
  • algorithm
  • Hash
  • 蓄水池
大约 1 分钟

🌕🌗 398. 随机数索引

难度: 🌕🌗

问题描述

img_66.png


解法 1 - Hash

class Solution {
    // 思路:
    // 在初始化时,将所有元素 和出现次数记录在 map 中
    // 时间复杂度 O(N) & O(1) 空间复杂度 O(N)
    HashMap<Integer, ArrayList<Integer>> map;
    Random rand;

    public Solution(int[] nums) {
        rand = new Random();
        map = new HashMap<>();
        // 复杂度 O(N)
        int len = nums.length;
        for(int i = 0; i < len; i ++) {
            int cur = nums[i];
            if(!map.containsKey(cur)) {
                ArrayList<Integer> tmp = new ArrayList<>();
                map.put(cur, tmp);
            } 
            ArrayList<Integer> list = map.get(cur);
            list.add(i);
            map.put(cur, list);
        }
    }
    
    public int pick(int target) {
        if(!map.containsKey(target)) {
            return -1;
        }
        // 复杂度 O(1)
        ArrayList<Integer> list = map.get(target);
        int size = list.size();
        int index = rand.nextInt(size);
        return list.get(index);
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int param_1 = obj.pick(target);
 */

输出 1

img_65.png


解法 2 - 蓄水池

class Solution {
    // 思路:
    // 常规思路是在初始化时保存所有元素和出现次数
    // 若大数据背景下,内存放不下文件系统中的所有元素,此时使用 map 存储超内存
    // 采用蓄水池算法
    // 在初始化时不做处理,在挑选随机数时,遍历 O(N) 但不存储所有元素,只有单个变量,此时空间复杂度就降低了
    // 时间复杂度 O(1) & O(N) 空间复杂度 O(1)
    Random rand;
    int[] nums;

    public Solution(int[] nums) {
        // 复杂度 O(1)
        rand = new Random();
        this.nums = nums;
    }
    
    public int pick(int target) {
        // 复杂度 O(N)
        int len = nums.length;
        int count = 0; // target 的出现次数
        int res = 0;
        for(int i = 0; i < len; i ++) {
            int cur = nums[i];
            if(cur == target) {
                // 只有目标出现时,才进行操作
                count ++;
                int index = rand.nextInt(count); // [0, count - 1] 中抽样,假设抽到 0 就进行替换
                if(index == 0) {
                    res = i;
                }
            }
        }
        return res;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(nums);
 * int param_1 = obj.pick(target);
 */

输出 2

img_67.png

上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou