Problem:
设计RandomPool结构
【题目】 设计一种结构,在该结构中有如下三个功能:
insert(key):将某个key加入到该结构,做到不重复加入。
delete(key):将原本在结构中的某个key移除。
getRandom():等概率随机返回结构中的任何一个key。
【要求】 Insert、delete和getRandom方法的时间复杂度都是O(1)
Solution:
使用两个hash表,一个是记录标号,一个记录关键词
这里有个关键之处就是,等概率返回一个关键词
若简单使用用哈希表来进行存储,那么有个问题,当删除数据时,会使得哈希表中间产生空白数据
最好的避免中间产生空数据的方法就是将要删除数据的与表中末尾的数据进行交换
然后直接删除最后的数据,故需要使用两个哈希表
Code:
1 #pragma once 2 #include <iostream> 3 #include <hash_map> 4 #include <string> 5 #include <time.h> 6 #include <stdlib.h> 7 8 using namespace std; 9 10 template<class T> 11 class RandomPool 12 { 13 public: 14 void insert(T key); 15 void del(T key); 16 T getRandom(); 17 void getPrint(T key); 18 void getPrint(int index); 19 20 private: 21 hash_map<T, int>KeyMap; 22 hash_map<int, T>IndexMap; 23 int size = 0; 24 }; 25 26 27 template<class T> 28 void RandomPool<T>::insert(T key) 29 { 30 if (KeyMap.find(key) == KeyMap.end()) 31 { 32 KeyMap[key] = this->size; 33 IndexMap[this->size] = key; 34 ++(this->size); 35 cout << "add succeed!" << endl; 36 } 37 else 38 cout << "add filed!" << endl; 39 } 40 41 42 template<class T> 43 void RandomPool<T>::del(T key) 44 { 45 auto ptr = KeyMap.find(key); 46 if (ptr == KeyMap.end()) 47 { 48 cout << "delete filed! there is not exsite the key!" << endl; 49 return; 50 } 51 //交换查找到元素与最后一个元素 52 T temp = IndexMap[--(this->size)];//最后一个元素的关键词,同时将hash表中的元素删除了 53 int index = KeyMap[key];//要删除元素的位置 54 KeyMap[temp] = index; 55 IndexMap[index] = temp;//将最后一个元素替换要删除元素的位置 56 //正式删除 57 KeyMap.erase(ptr); 58 IndexMap.erase(IndexMap.find(index)); 59 } 60 61 template<class T> 62 T RandomPool<T>::getRandom() 63 { 64 if (this->size == 0) 65 { 66 cout << "the map is empty!" << endl; 67 } 68 else 69 { 70 int index = (int)((rand() % (99 + 1) / (double)(99 + 1))*(this->size));//随机生成一个位置 71 return IndexMap[index]; 72 } 73 } 74 75 template<class T> 76 void RandomPool<T>::getPrint(T key) 77 { 78 if (KeyMap.find(key) == KeyMap.end()) 79 cout << "the key is not exsite!" << endl; 80 else 81 cout << KeyMap[key] << endl; 82 } 83 84 template<class T> 85 void RandomPool<T>::getPrint(int index) 86 { 87 if (IndexMap.find(index) == IndexMap.end()) 88 cout << "the key is not exsite!" << endl; 89 else 90 cout << IndexMap[index] << endl; 91 } 92 93 94 void Test() 95 { 96 srand((unsigned)time(NULL)); 97 RandomPool<string>map; 98 map.insert("zz"); 99 map.insert("zw"); 100 map.insert("ww"); 101 map.insert("wz"); 102 103 cout << map.getRandom() << endl; 104 map.getPrint(2); 105 map.getPrint("ww"); 106 map.del("zw"); 107 map.getPrint("zw"); 108 }