题目 设计一种结构,在该结构中有如下三个功能:
insert(key):将某个key加入到该结构,做到不重复加入。
delete(key):将原本在结构中的某个key移除。
getRandom(): 等概率随机返回结构中的任何一个key。
要求 Insert、delete和getRandom方法的时间复杂度都是 O(1)。
思路 设置两个哈希表map1和map2,结构分别为<K, Integer>和<Integer, K>,设置一个整型记录哈希表当前大小。其中K是泛型,可以是任何类型,比如字符串类型等等;Integer记录K类型的数据是map中的第几条数据,作为序号。
(1)insert时,为保证输入数据不重复,需要先判断表中是否已经有了该数据,若没有,则将其分别put到map1和map2中;
(2)detele时,先判断map中是否存在key,若存在,则在map1中根据给定的key找到其对应的序号index,然后将序号最末的数据覆盖到第index条数据上,最后在map1和map2中将序号最末的数据删掉。
(3)利用Math.random()函数随机生成[0,1)的数据,再将其乘上size,得到随机的序号,返回对应的值即可。
package algorithm.section6;
import java.util.HashMap;
public class RandomPool<K> {
private HashMap<K, Integer> map1;
private HashMap<Integer, K> map2;
private int size;
public RandomPool(){
map1 = new HashMap<>();
map2 = new HashMap<>();
size = 0;
}
public void insert(K val){
if (!map1.containsKey(val)) {
map1.put(val, size);
map2.put(size, val);
size++;
}
}
public void delete(K val){
if (map1.containsKey(val)){
int index = map1.get(val);
map1.put(map2.get(size - 1), index);
map2.put(index, map2.get(size - 1));
map1.remove(map2.get(size - 1));
map2.remove(size - 1);
size--;
}
}
public K getRandom(){
if (map1.size() > 0) {
int index = (int) (Math.random() * size);
return map2.get(index);
} else
return null;
}
public static void main(String[] args){
RandomPool<String> str = new RandomPool<>();
str.insert("zhang");
str.insert("xue");
str.insert("jia");
str.insert("you");
System.out.println(str.getRandom());
str.delete("zhang");
System.out.println(str.getRandom());
System.out.println(str.getRandom());
System.out.println(str.getRandom());
System.out.println(str.getRandom());
System.out.println(str.getRandom());
System.out.println(str.getRandom());
}
}