题目来源:LeetCode 398:随机数索引
问题抽象: 设计一个 Solution 类,用于高效处理给定数组中元素的索引随机查询,满足以下核心需求:
-
核心功能:
- 初始化:接收整数数组
nums(可含重复元素); - 随机索引查询:
pick(target)返回target在nums中的 随机一个有效索引(所有索引等概率)。
- 初始化:接收整数数组
-
概率约束:
- 若
target在数组中重复出现k次(索引集{i₁, i₂, ..., iₖ}),则每次pick(target)返回任意索引iⱼ的概率为1/k; - 多次调用同一
target的pick结果相互独立。
- 若
-
数据结构要求:
- 预处理优化:初始化时构建 哈希映射(键为元素值,值为索引列表);
- 高效查询:
pick操作需 O(1) 时间(随机访问索引列表); - 空间换时间:空间复杂度 O(n)(存储所有元素的索引映射)。
-
边界处理:
- 空数组:题目保证
pick调用时target必存在(无需处理不存在情况); - 单元素数组:
pick(target)唯一解; - 高频调用:支持多次调用
pick(不同或相同target); - 重复元素:如
nums=[1,2,3,3,3],pick(3)返回索引2,3,4的概率各1/3。
- 空数组:题目保证
-
计算约束:
- 初始化时间复杂度 O(n):遍历数组构建哈希映射;
pick时间复杂度 O(1):生成随机数并访问列表;- 输入规模:
- 数组长度
n ≤ 2×10^4; pick调用次数≤ 10^4。
- 数组长度
类定义:
class Solution {
public Solution(int[] nums) { // 初始化数据结构
public int pick(int target) { // 返回target的随机索引
}
解题思路
题目要求设计一个数据结构,支持从数组中随机返回目标值的索引,且每个索引的返回概率必须相等。核心问题在于高效处理多次查询。解题策略如下:
- 空间换时间:在初始化阶段遍历数组,用哈希表记录每个数值对应的所有索引(列表存储)。
- O(1)查询:执行
pick时,直接从哈希表中获取目标值的索引列表,用随机数生成器选择一个索引返回。 - 概率均等:随机数范围是
[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()));
}
}
代码说明
-
数据结构:
valToIndices:HashMap类型,键为数组元素值,值为该值在数组中所有出现位置的索引列表。random:Random实例,用于生成随机索引。
-
初始化流程:
- 遍历输入数组
nums,对每个元素:- 若值未在哈希表中,创建新列表。
- 将当前索引加入该值对应的列表。
- 遍历输入数组
-
pick方法:
- 从
valToIndices中获取target对应的索引列表。 - 用
random.nextInt(indices.size())生成随机索引,返回列表中该位置的索引值。
- 从
-
复杂度分析:
- 时间复杂度:初始化
O(n),pick操作O(1)。 - 空间复杂度:
O(n),存储所有索引。
- 时间复杂度:初始化
提交详情(执行用时、内存消耗)

918

被折叠的 条评论
为什么被折叠?



