题目
实现一个Set,要求
add O(1)
remove O(1)
random O(1)
分析
同时使用两种数据结构
ArrayList: 保存所有元素
HashMap: key为元素,value为元素在ArrayList中的下标
add:
ArrayList.add O(1)
HashMap add O(1)
random: ArrayList里随机取一个值
remove:
HashMap中找到元素在ArrayList中的下标 O(1)
删除HashMap中的元素 O(1)
将ArrayList最后一个元素copy到删除元素所在位置 O(1)
删除最后一个元素 O(1)
更新被copy元素在HashMap中的value O(1)
代码
public class RandomSet<E> {
List<E> dta = new ArrayList<E>();
Map<E, Integer> idx = new HashMap<E, Integer>();
public boolean add(E item) {
if (idx.containsKey(item)) {
return false;
}
idx.put(item, dta.size());
dta.add(item);
return true;
}
public E removeAt(int id) {
if (id >= dta.size()) {
return null;
}
E res = dta.get(id);
idx.remove(res);
E last = dta.remove(dta.size() - 1);
// skip filling the hole if last is removed
if (id < dta.size()) {
idx.put(last, id);
dta.set(id, last);
}
return res;
}
public boolean remove(E item) {
Integer id = idx.get(item);
if (id == null) {
return false;
}
removeAt(id);
return true;
}
public E random(Random rnd) {
if (dta.isEmpty()) {
return null;
}
int id = rnd.nextInt(dta.size());
return removeAt(id);
}
}