题目:
设计一种结构,在该结构中有如下三个功能:
insert(key):将某个key加入到该结构,做到不重复加入。
delete(key):将原本在结构中的某个key移除。
getRandom(): 等概率随机返回结构中的任何一个key。
【要求】 Insert、delete和getRandom方法的时间复杂度都是 O(1)
分析:这个结构一看感觉跟哈希表的结构比较像,但是哈希表是get<key,value> 这道题只用get key还有就是一个哈希表不能严格做到等概率 时间复杂度O(1)的返回key,因为当样本量小的时候,数据做不到均匀分布,样本量多了可以看成是均匀分布,但是等概率是不可能的。所以删除有个技巧,会在代码中体现。
public static class Pool<T>{
private HashMap<T,Integer> keyIntegerMap;
private HashMap<Integer, T> integerKeyMap;
private int size;
public Pool(){
this.keyIntegerMap = new HashMap<T, Integer>();
this.integerKeyMap = new HashMap<Integer, T>();
this.size = 0;
}
public void insert(T key) {
if(!this.keyIntegerMap.containsKey(key)) {//做到不重复加入
this.keyIntegerMap.put(key, this.size);
this.integerKeyMap.put(this.size++, key);
}
}
/*
* 删除的时候,如果直接删除key那么在这个范围上会缺一个“洞”,当有1000个数据,删除了999个
* 那么在等概率获取值的时候,生成的随机不一定会直接到最后存在的那个数据。就需要在返回生成新的随机数
* 所以需要在删除这个地方有个技巧。在删除当前值的时候。我们把最后的一个值放在当前值的位置上,再remove最后一个值,size--就行了
*/
public void delete(T key) {
if(this.keyIntegerMap.containsKey(key)) {
int deleteIndex = this.keyIntegerMap.get(key);//得到这个key的对应值,在integerKeyMap中删除
int lastIndex = --this.size;
T lastKey = this.integerKeyMap.get(lastIndex);
this.integerKeyMap.put(deleteIndex, lastKey);
this.keyIntegerMap.put(lastKey, deleteIndex);
this.integerKeyMap.remove(deleteIndex);
this.keyIntegerMap.remove(lastKey);
}
}
//等概率的获得key,需要可以使用随机数,和已经标记的size。
public T getRandom() {
if (this.size == 0) {
return null;
}
int randomIndex = (int) (Math.random() * this.size); // 0 ~ size -1
return this.integerKeyMap.get(randomIndex);
}
}
新人第一次写博客,想要记录一下自己在学习过程中的收获。希望大家多多关照