【中等】力扣算法题解析LeetCode398:随机数索引

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode 398:随机数索引

问题抽象: 设计一个 Solution 类,用于高效处理给定数组中元素的索引随机查询,满足以下核心需求:

  1. 核心功能

    • 初始化:接收整数数组 nums(可含重复元素);
    • 随机索引查询pick(target) 返回 targetnums 中的 随机一个有效索引(所有索引等概率)。
  2. 概率约束

    • target 在数组中重复出现 k 次(索引集 {i₁, i₂, ..., iₖ}),则每次 pick(target) 返回任意索引 iⱼ 的概率为 1/k
    • 多次调用同一 targetpick 结果相互独立。
  3. 数据结构要求

    • 预处理优化:初始化时构建 哈希映射(键为元素值,值为索引列表);
    • 高效查询pick 操作需 O(1) 时间(随机访问索引列表);
    • 空间换时间:空间复杂度 O(n)(存储所有元素的索引映射)。
  4. 边界处理

    • 空数组:题目保证 pick 调用时 target 必存在(无需处理不存在情况);
    • 单元素数组pick(target) 唯一解;
    • 高频调用:支持多次调用 pick(不同或相同 target);
    • 重复元素:如 nums=[1,2,3,3,3]pick(3) 返回索引 2,3,4 的概率各 1/3
  5. 计算约束

    • 初始化时间复杂度 O(n):遍历数组构建哈希映射;
    • pick 时间复杂度 O(1):生成随机数并访问列表;
    • 输入规模:
      • 数组长度 n ≤ 2×10^4
      • pick 调用次数 ≤ 10^4

类定义

class Solution {
    public Solution(int[] nums) {  // 初始化数据结构  
    public int pick(int target) {  // 返回target的随机索引  
}  

解题思路

题目要求设计一个数据结构,支持从数组中随机返回目标值的索引,且每个索引的返回概率必须相等。核心问题在于高效处理多次查询。解题策略如下:

  1. 空间换时间:在初始化阶段遍历数组,用哈希表记录每个数值对应的所有索引(列表存储)。
  2. O(1)查询:执行pick时,直接从哈希表中获取目标值的索引列表,用随机数生成器选择一个索引返回。
  3. 概率均等:随机数范围是[0, 列表长度-1],保证每个索引被选中的概率相同。

该方法将初始化时间复杂度控制在O(n),查询时间复杂度优化到O(1),空间复杂度为O(n)。相比每次遍历数组的解法(查询O(n)),该方案在多次查询时性能更优。


代码实现(Java版)🔥点击下载源码

class Solution {
    private HashMap<Integer, List<Integer>> valToIndices; // 存储值到索引列表的映射
    private Random random; // 随机数生成器

    // 初始化:遍历数组,构建哈希表
    public Solution(int[] nums) {
        valToIndices = new HashMap<>();
        random = new Random();
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            // 若值未出现过,新建索引列表
            if (!valToIndices.containsKey(num)) {
                valToIndices.put(num, new ArrayList<>());
            }
            // 将当前索引加入列表
            valToIndices.get(num).add(i);
        }
    }
    
    // 随机返回目标值的索引
    public int pick(int target) {
        List<Integer> indices = valToIndices.get(target);
        // 生成[0, size-1]的随机索引,返回对应位置的值
        return indices.get(random.nextInt(indices.size()));
    }
}


代码说明

  1. 数据结构

    • valToIndicesHashMap类型,键为数组元素值,值为该值在数组中所有出现位置的索引列表。
    • randomRandom实例,用于生成随机索引。
  2. 初始化流程

    • 遍历输入数组nums,对每个元素:
      • 若值未在哈希表中,创建新列表。
      • 将当前索引加入该值对应的列表。
  3. pick方法

    • valToIndices中获取target对应的索引列表。
    • random.nextInt(indices.size())生成随机索引,返回列表中该位置的索引值。
  4. 复杂度分析

    • 时间复杂度:初始化O(n)pick操作O(1)
    • 空间复杂度O(n),存储所有索引。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值