LeetCode380 常数时间插入、删除和获取随机元素
LeetCode380 常数时间插入、删除和获取随机元素
题目要求
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。
insert(val):当元素 val 不存在时,向集合中插入该项。
remove(val):元素 val 存在时,从集合中移除该项。
getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
示例 :
// 初始化一个空的集合。
RandomizedSet randomSet = new RandomizedSet();
// 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomSet.insert(1);
// 返回 false ,表示集合中不存在 2 。
randomSet.remove(2);
// 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
randomSet.insert(2);
// getRandom 应随机返回 1 或 2 。
randomSet.getRandom();
// 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
randomSet.remove(1);
// 2 已在集合中,所以返回 false 。
randomSet.insert(2);
// 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
randomSet.getRandom();
分析:
查找最快的数据结构为列表或者hash表,分别按照角标或者内容查找。
删除元素hash表时间复杂度为常数时间,但是列表则为线性时间,本题需要做特殊处理,对于要删除的元素采用交换到末尾的策略,然后删除末尾元素再更新对应的hash表。

代码:
class RandomizedSet {
public:
    /** Initialize your data structure here. */
    RandomizedSet() {
    }
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    bool insert(int val) {
        if(hashMap.find(val) != hashMap.end()) {
            return false;
        }
        vec.push_back(val);
        hashMap[val] = vec.size()-1;
        return true;
    }
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if(hashMap.find(val) == hashMap.end()) {
            return false;
        }
        int index = hashMap.find(val) -> second;
        if(index == vec.size() - 1) {
            vec.pop_back();
            hashMap.erase(val);
        }else {
            hashMap[vec[vec.size()-1]] = index;
            swap(vec[index], vec[vec.size() - 1]);
            vec.pop_back();
            hashMap.erase(val);
        }
        return true;
    }
    /** Get a random element from the set. */
    int getRandom() {
        if(!vec.size()) {
            return -1;
        }
        int index = rand() % vec.size();
        return vec[index];
    }
private:
    unordered_map<int, int> hashMap;
    vector<int> vec;
};
/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet* obj = new RandomizedSet();
 * bool param_1 = obj->insert(val);
 * bool param_2 = obj->remove(val);
 * int param_3 = obj->getRandom();
 */
LeetCode380 常数时间插入、删除和获取随机元素的更多相关文章
- Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
		380. 常数时间插入.删除和获取随机元素 设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构. insert(val):当元素 val 不存在时,向集合中插入该项. remove( ... 
- LeetCode 381. Insert Delete GetRandom O(1) - Duplicates allowed O(1) 时间插入、删除和获取随机元素 - 允许重复(C++/Java)
		题目: Design a data structure that supports all following operations in averageO(1) time. Note: Duplic ... 
- Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素 - 允许重复
		381. O(1) 时间插入.删除和获取随机元素 - 允许重复 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插 ... 
- 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
		381. O(1) 时间插入.删除和获取随机元素 - 允许重复 LeetCode_381 题目详情 题解分析 代码实现 package com.walegarrett.interview; impor ... 
- Leetcode 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
		1.题目描述 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插入元素 val. remove(val):当 va ... 
- LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)
		题目: Design a data structure that supports all following operations in averageO(1) time. insert(val): ... 
- LeetCode 哈希表 380. 常数时间插入、删除和获取随机元素(设计数据结构 List HashMap底层 时间复杂度)
		比起之前那些问计数哈希表的题目,这道题好像更接近哈希表的底层机制. java中hashmap的实现是通过List<Node>,即链表的list,如果链表过长则换为红黑树,如果容量不足(装填 ... 
- [Swift]LeetCode381. O(1) 时间插入、删除和获取随机元素 - 允许重复 | Insert Delete GetRandom O(1) - Duplicates allowed
		Design a data structure that supports all following operations in averageO(1) time. Note: Duplicate ... 
- 381 Insert Delete GetRandom O(1) - Duplicates allowed O(1) 时间插入、删除和获取随机元素 - 允许重复
		设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构.注意: 允许出现重复元素. insert(val):向集合中插入元素 val. remove(val):当 val ... 
随机推荐
- maven的编译规范
			maven的中央仓库上的jar的包名必须小写.否则maven编译不通过. 如:Memcached-Java-Client-3.0.2 的jar包. 目录如下: com.whalin.memcached ... 
- Python机器学习·微教程
			Python目前是机器学习领域增长最快速的编程语言之一. 该教程共分为11小节.在这个教程里,你将学会: 如何处理数据集,并构建精确的预测模型 使用Python完成真实的机器学习项目 这是一个非常简洁 ... 
- jquery EasyUi 添加节点、展开所有节点、默认选中第一个节点
			感觉easyUi 的树用起来不如 Ext 的树方便,首先,root节点不太好自定义, 异步加载时,只能通过后台判断生成root节点,但是这样一来有一个问题,就是第一次访问界面时, 树的初始化比较慢,大 ... 
- [NUnit]No results
			Results (nunit3) saved as TestResult.xmlCommitting...No results, this could be for a number of reaso ... 
- 从boosting谈起
			Boosting 将一些表现效果一般(可能仅仅优于随机猜测)的模型通过特定方法进行组合来获得一个表现效果较好的模型.抽象地说,模型的训练过程是对一任意可导目标函数的优化过程. Adaptive boo ... 
- Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端
			多线程的操作在程序中也是比较常见的,比如开启一个线程执行一些比较耗时的操作(IO操作),而主线程继续执行当前操作,不会造成主线程阻塞.线程又分为前台线程和后台线程,区别是:整个程序必须要运行完前台线程 ... 
- Alfred Workflow
			实用的 Alfred Workflow Alfred Workflow 介绍 alfred-pkgman-workflow 快速从各个软件仓库(maven, gradle 等等)中查找需要的软件包 A ... 
- Docker 前沿概述
			目录 Docker 前沿概述 什么是Docker? Docker的基本概念 容器(Container) -- 镜像运行时的实体 镜像(Image) -- 一个特殊的文件系统 仓库(Repository ... 
- 重学计算机组成原理(七)- 程序无法同时在Linux和Windows下运行?
			既然程序最终都被变成了一条条机器码去执行,那为什么同一个程序,在同一台计算机上,在Linux下可以运行,而在Windows下却不行呢? 反过来,Windows上的程序在Linux上也是一样不能执行的 ... 
- lxml解析网页
			目录 1. 什么是lxml 2. 初次使用 3. xpath 3.2 标签定位 3.3 序列定位 3.4 轴定位 4. 实例 1. 什么是lxml lxml是干什么的?简单的说来,lxml是帮助我们解 ... 
