左神算法基础班5_1设计RandomPool结构
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结构的更多相关文章
- 左神算法基础班4_1&2实现二叉树的先序、中序、后序遍历,包括递归方式和非递归
Problem: 实现二叉树的先序.中序.后序遍历,包括递归方式和非递归方式 Solution: 切记递归规则: 先遍历根节点,然后是左孩子,右孩子, 根据不同的打印位置来确定中序.前序.后续遍历. ...
- 左神算法进阶班5_4设计可以变更的缓存结构(LRU)
[题目] 设计一种缓存结构,该结构在构造时确定大小,假设大小为K,并有两个功能: set(key, value):将记录(key, value)插入该结构. get(key):返回key对应的valu ...
- 左神算法进阶班1_5BFPRT算法
在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BF ...
- 左神算法进阶班3_1构造数组的MaxTree
题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一 ...
- 左神算法进阶班1_4Manacher算法
#include <iostream> #include <string> using namespace std; //使用manacher算法寻找字符中最长的回文子串 in ...
- 左神算法进阶班1_1添加最少字符得到原字符N次
Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最 ...
- 左神算法进阶班4_2累加和为aim的最长子数组
[题目] 给定一个数组arr,和一个整数aim,求在arr中,累加和等于num的最长子数组的长度 例子: arr = { 7,3,2,1,1,7,7,7 } aim = 7 其中有很多的子数组累加和等 ...
- 左神算法进阶班8_1数组中累加和小于等于aim的最长子数组
[题目] 给定一个数组arr,全是正数:一个整数aim,求累加和小于等于aim的,最长子数组,要求额外空间复杂度O(1),时间复杂度O(N) [题解] 使用窗口: 双指针,当sum <= aim ...
- 左神算法进阶班6_1LFU缓存实现
[题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前 ...
随机推荐
- 关于MySQL的insert添加自动获取日期的now()的用法
例如我的MySQL数据库里有个表table1,它的字段有id,date1,date2,除id外都是Datetime类型的.那么插值语句这样写:insert into table1(date1,date ...
- 41. wait notify 方法
wait() 等待,如果一个线程执行了wait方法,那么该线程就会进去一个以锁对象为标识符的线程池中等待 notity() 唤醒,如果一个线程执行了notity方法,那么就会唤醒以锁对象为标识符的线 ...
- 线程池 一 ThreadPoolExecutor
java.util.concurrent public class ThreadPoolExecutor extends AbstractExecutorService ThreadPoolExecu ...
- Struts功能详解——ActionForm
ActionForm ActionForm用于封装用户的请求参数,而请求参数是通过JSP页面的表单域传递过来的.因此应保证ActionForm的参数,与表单域的名字相同. ActionForm ...
- splay 模板 洛谷3369
题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入 xx 数 删除 xx 数(若有多个相同的数,因只删除一个) 查询 xx 数的排名(排名定义为比当前数小的数 ...
- MTT:任意模数NTT
MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MT ...
- Android studio 安装apk时报错:INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries
flutter项目 华为手机真机安装报错,解决 办法 app build.gradle android {...}内添加一下代码 splits { abi { enable true reset() ...
- (转) MySQL中索引的限制
转:http://book.51cto.com/art/200906/132459.htm 8.4.8 MySQL中索引的限制 在使用索引的同时,还应该了解MySQL 中索引存在的限制,以便在索引应 ...
- P1910 L国的战斗之间谍
P1910 L国的战斗之间谍 题目背景 L国即将与I国发动战争!! 题目描述 俗话说的好:“知己知彼,百战不殆”.L国的指挥官想派出间谍前往I国,于是,选人工作就落到了你身上. 你现在有N个人选,每个 ...
- shell脚本实现GoDaddy中IPv6的动态域名解析(DDNS)_可在路由中运行
首先谈一下个人的需求,家里路由拿到了运营商的外网ipv6地址,于是想着将路由的各种服务通过DDNS放到外网上来,这才有下面的动态域名解析折腾.废话不多说,进入正题. 1.首先在godaddy中注册域名 ...