LeetCode 380: O(1) 时间插入、删除和获取随机元素

这道题的难点在于如何同时满足三个 O(1) 操作,尤其是随机获取元素

代码逻辑

1. 插入操作 (insert)
java 复制代码
public boolean insert(int val) {
    if (map.containsKey(val)) {
        return false;  // 元素已存在
    }
    map.put(val, arr.size());  // 记录新元素的索引
    arr.add(val);               // 添加到数组末尾
    return true;
}
2. 删除操作 (remove)

直接从数组中间删除元素的时间复杂度是 O(n),因此本文采用交换删除法:

java 复制代码
public boolean remove(int val) {
    if (!map.containsKey(val)) {
        return false;  // 元素不存在
    }
    
    // 获取要删除元素的索引
    int valIndex = map.get(val);
    
    // 获取数组最后一个元素
    int endValue = arr.get(arr.size() - 1);
    
    // 用最后一个元素覆盖要删除的元素
    map.put(endValue, valIndex);
    arr.set(valIndex, endValue);
    
    // 删除 map 中的记录和数组末尾元素
    map.remove(val);
    arr.remove(arr.size() - 1);
    
    return true;
}

将要删除的元素与数组最后一个元素交换,然后删除末尾元素,这样删除操作就是 O(1) 了!

3. 随机获取 (getRandom)
java 复制代码
public int getRandom() {
    return arr.get((int) (Math.random() * arr.size()));
}

使用了 ArrayList,可以通过索引 O(1) 访问任意元素,配合随机数生成器即可实现等概率随机返回。

完整代码

java 复制代码
class RandomizedSet{
        public HashMap<Integer,Integer> map;
        public ArrayList<Integer> arr;
        public RandomizedSet(){
            map = new HashMap<>();
            arr = new ArrayList<>();
        }

        public boolean insert(int val) {
            if (map.containsKey(val)) {
                return false;  // 元素已存在
            }
            map.put(val, arr.size());  // 记录新元素的索引
            arr.add(val);               // 添加到数组末尾
            return true;
        }

        public boolean remove(int val) {
            if (!map.containsKey(val)) {
                return false;  // 元素不存在
            }

            // 获取要删除元素的索引
            int valIndex = map.get(val);

            // 获取数组最后一个元素
            int endValue = arr.get(arr.size() - 1);

            // 用最后一个元素覆盖要删除的元素
            map.put(endValue, valIndex);
            arr.set(valIndex, endValue);

            // 删除 map 中的记录和数组末尾元素
            map.remove(val);
            arr.remove(arr.size() - 1);

            return true;
        }

        public int getRandom(){
            return arr.get((int) (Math.random()*arr.size()));
        }
    }
相关推荐
I_LPL9 小时前
day23 代码随想录算法训练营 回溯专题2
算法·hot100·回溯算法·求职面试
智者知已应修善业9 小时前
【洛谷P9975奶牛被病毒传染最少数量推导,导出多样例】2025-2-26
c语言·c++·经验分享·笔记·算法·推荐算法
m0_736919109 小时前
C++中的委托构造函数
开发语言·c++·算法
小小小小王王王9 小时前
洛谷-P1886 【模板】单调队列 / 滑动窗口
c++·算法
callJJ9 小时前
Spring AI 文本聊天模型完全指南:ChatModel 与 ChatClient
java·大数据·人工智能·spring·spring ai·聊天模型
CBeann9 小时前
企业级规则引擎落地实战:动态脚本引擎 QLExpress ,真香!
java·ai·大模型·规则引擎·qlexpress·大厂实战项目
懈尘9 小时前
从 Java 1.7 到 Java 21:逐版本深入解析新特性与平台演进
java·开发语言
亓才孓9 小时前
[Maven]Maven基础
java·maven
hello 早上好10 小时前
05_Java 类加载过程
java·开发语言
PPPPPaPeR.10 小时前
光学算法实战:深度解析镜片厚度对前后表面折射/反射的影响(纯Python实现)
开发语言·python·数码相机·算法