Problem:
  设计RandomPool结构
  【题目】 设计一种结构,在该结构中有如下三个功能:
    insert(key):将某个key加入到该结构,做到不重复加入。
    delete(key):将原本在结构中的某个key移除。
    getRandom():等概率随机返回结构中的任何一个key。

  【要求】 Insert、delete和getRandom方法的时间复杂度都是O(1)

Solution:
  使用两个hash表,一个是记录标号,一个记录关键词
  这里有个关键之处就是,等概率返回一个关键词
  若简单使用用哈希表来进行存储,那么有个问题,当删除数据时,会使得哈希表中间产生空白数据
  最好的避免中间产生空数据的方法就是将要删除数据的与表中末尾的数据进行交换
  然后直接删除最后的数据,故需要使用两个哈希表

Code:  

 #pragma once
#include <iostream>
#include <hash_map>
#include <string>
#include <time.h>
#include <stdlib.h> using namespace std; template<class T>
class RandomPool
{
public:
void insert(T key);
void del(T key);
T getRandom();
void getPrint(T key);
void getPrint(int index); private:
hash_map<T, int>KeyMap;
hash_map<int, T>IndexMap;
int size = ;
}; template<class T>
void RandomPool<T>::insert(T key)
{
if (KeyMap.find(key) == KeyMap.end())
{
KeyMap[key] = this->size;
IndexMap[this->size] = key;
++(this->size);
cout << "add succeed!" << endl;
}
else
cout << "add filed!" << endl;
} template<class T>
void RandomPool<T>::del(T key)
{
auto ptr = KeyMap.find(key);
if (ptr == KeyMap.end())
{
cout << "delete filed! there is not exsite the key!" << endl;
return;
}
//交换查找到元素与最后一个元素
T temp = IndexMap[--(this->size)];//最后一个元素的关键词,同时将hash表中的元素删除了
int index = KeyMap[key];//要删除元素的位置
KeyMap[temp] = index;
IndexMap[index] = temp;//将最后一个元素替换要删除元素的位置
//正式删除
KeyMap.erase(ptr);
IndexMap.erase(IndexMap.find(index));
} template<class T>
T RandomPool<T>::getRandom()
{
if (this->size == )
{
cout << "the map is empty!" << endl;
}
else
{
int index = (int)((rand() % ( + ) / (double)( + ))*(this->size));//随机生成一个位置
return IndexMap[index];
}
} template<class T>
void RandomPool<T>::getPrint(T key)
{
if (KeyMap.find(key) == KeyMap.end())
cout << "the key is not exsite!" << endl;
else
cout << KeyMap[key] << endl;
} template<class T>
void RandomPool<T>::getPrint(int index)
{
if (IndexMap.find(index) == IndexMap.end())
cout << "the key is not exsite!" << endl;
else
cout << IndexMap[index] << endl;
} void Test()
{
srand((unsigned)time(NULL));
RandomPool<string>map;
map.insert("zz");
map.insert("zw");
map.insert("ww");
map.insert("wz"); cout << map.getRandom() << endl;
map.getPrint();
map.getPrint("ww");
map.del("zw");
map.getPrint("zw");
}

左神算法基础班5_1设计RandomPool结构的更多相关文章

  1. 左神算法基础班4_1&2实现二叉树的先序、中序、后序遍历,包括递归方式和非递归

    Problem: 实现二叉树的先序.中序.后序遍历,包括递归方式和非递归方式 Solution: 切记递归规则: 先遍历根节点,然后是左孩子,右孩子, 根据不同的打印位置来确定中序.前序.后续遍历. ...

  2. 左神算法进阶班5_4设计可以变更的缓存结构(LRU)

    [题目] 设计一种缓存结构,该结构在构造时确定大小,假设大小为K,并有两个功能: set(key, value):将记录(key, value)插入该结构. get(key):返回key对应的valu ...

  3. 左神算法进阶班1_5BFPRT算法

    在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BF ...

  4. 左神算法进阶班3_1构造数组的MaxTree

    题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一 ...

  5. 左神算法进阶班1_4Manacher算法

    #include <iostream> #include <string> using namespace std; //使用manacher算法寻找字符中最长的回文子串 in ...

  6. 左神算法进阶班1_1添加最少字符得到原字符N次

    Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最 ...

  7. 左神算法进阶班4_2累加和为aim的最长子数组

    [题目] 给定一个数组arr,和一个整数aim,求在arr中,累加和等于num的最长子数组的长度 例子: arr = { 7,3,2,1,1,7,7,7 } aim = 7 其中有很多的子数组累加和等 ...

  8. 左神算法进阶班8_1数组中累加和小于等于aim的最长子数组

    [题目] 给定一个数组arr,全是正数:一个整数aim,求累加和小于等于aim的,最长子数组,要求额外空间复杂度O(1),时间复杂度O(N) [题解] 使用窗口: 双指针,当sum <= aim ...

  9. 左神算法进阶班6_1LFU缓存实现

    [题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前 ...

随机推荐

  1. JAVA去除抖音视频的水印源码!!!

    @PostMapping("geturl") public DataResponse decodeDouiyin(@RequestBody DouyinRequest req ) ...

  2. pymupdf 修改pdf文件

    安装: sudo pip install pymupdf==1.16.0 引入使用: import  fitz 可以插入文字.图片.... 帮助文档: PyMuPDF documentation ht ...

  3. 2019hdu第二场

    10:签到求n!取模 #include <iostream> #include <iterator> #include <algorithm> typedef lo ...

  4. hdu多校第一场1004(hdu6581)Vacation 签到

    题意:有n+1辆车,每辆车都有一定的长度,速度和距离终点的距离,第1-n辆车在前面依次排列,第0辆车在最后面.不允许超车,一旦后车追上前车,后车就减速,求第0辆车最快什么时候能到达终点? 思路:对于每 ...

  5. CPUID 指令的使用

    使用 CPUID 指令可以从 processor 厂商里获得关于 processor 的详细信息,CPUID 指令是从 Intel 486 处理器以后开始加入支持. 1. 检测处理器是否支持 cpui ...

  6. Codeforces 1182A Filling Shapes

    题目链接:http://codeforces.com/problemset/problem/1182/A 思路:n为奇数时不可能完全填充,ans = 0.发现若要完全填充,每俩列可产生俩种情况,所以为 ...

  7. Ant属性文件

    直接在构建文件中设置属性是好的,如果你使用的是少数属性.然而,对于一个大型项目,是要存储在一个单独的属性文件中. 存储在一个单独的文件中的属性可以让你重复使用相同的编译文件,针对不同的执行环境不同的属 ...

  8. HTTP请求默认值

    填写后,后面的请求如果对应的未填写,默认使用该参数

  9. Selenium(二)---无界面模式+滑动底部

    一.使用无界面模式 1.正常情况启动 selenium 是有界面的 2.有些情况下,需要不显示界面,这时只要设置一下参数就可以实现了 # 不想显示界面可以用 Chrome——配置一下参数就好 from ...

  10. 23种常用设计模式的UML类图

    23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...