前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Leetcode 380: O(1)时间插入、删除和获取随机元素

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

作者头像
千灵域
发布2022-06-17 12:57:50
3650
发布2022-06-17 12:57:50
举报
文章被收录于专栏:challenge filterchallenge filter

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

22年4月13日每日一题

初始想法

最简单的想法是数组,但是数组的插入和删除并不是O(1)的。如果使用哈希表的话,插入和删除是O(1)的,但是随机化并不是O(1)。

因此,只需要将数组和哈希表结合起来,使用哈希表进行插入和删除,并使用数组来进行随机化。问题在于数组中的元素删除代价不一定是O(1),这个可以使用最后元素的置换来完成。

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <map>
#include <ctime>
using namespace std;

class RandomizedSet {
public:
    map<int,int> store;
    vector<int> q;
    RandomizedSet() {
        store.clear();
        q.clear();
    }
    
    bool insert(int val) {
        if(store.find(val)==store.end()){
            q.emplace_back(val);
            store[val] = q.size()-1;
            return true;
        }

        return false;
    }
    
    bool remove(int val) {
        if(store.find(val)==store.end()){
            return false;
        }

        int cur_pos = store[val];
        int last_pos = q.size()-1;
        if(cur_pos != last_pos){ // 将要删除的元素换到最末尾
            int last_val = q[last_pos];
            q[cur_pos] = last_val;
            store[last_val] = cur_pos;
        }
        q.pop_back();
        store.erase(val);
        return true;
    }
    
    int getRandom() {
        int num = rand()%q.size();
        return q[num];
    }
};



int main(void){
    RandomizedSet s;
    s.insert(1);
    s.insert(2);
    s.insert(3);
    s.insert(4);
    cout<<s.getRandom()<<endl;

    return 0;
}

执行用时:256 ms, 在所有 C++ 提交中击败了5.50%的用户 内存消耗:95 MB, 在所有 C++ 提交中击败了5.42%的用户

通过测试用例: 19 / 19

最终结果比较一般。

改进

官方的做法比较一致,但是使用unorder_map代替map,因为map是用红黑树做的,unordered_map是用哈希表做的,因此两者操作上具有差距。

代码语言:javascript
复制
class RandomizedSet {
public:
    RandomizedSet() {
        srand((unsigned)time(NULL));
    }
    
    bool insert(int val) {
        if (indices.count(val)) {
            return false;
        }
        int index = nums.size();
        nums.emplace_back(val);
        indices[val] = index;
        return true;
    }
    
    bool remove(int val) {
        if (!indices.count(val)) {
            return false;
        }
        int index = indices[val];
        int last = nums.back();
        nums[index] = last;
        indices[last] = index;
        nums.pop_back();
        indices.erase(val);
        return true;
    }
    
    int getRandom() {
        int randomIndex = rand()%nums.size();
        return nums[randomIndex];
    }
private:
    vector<int> nums;
    unordered_map<int, int> indices;
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Leetcode 380: O(1)时间插入、删除和获取随机元素
    • 初始想法
      • 改进
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档