设计一个支持在平均?时间复杂度 O(1)?下,执行以下操作的数据结构:
insert(val):当元素 val 不存在时返回 true?,并向集合中插入该项,否则返回 false 。 remove(val):当元素 val 存在时返回 true?,并从集合中移除该项,否则返回 false?。 getRandom:随机返回现有集合中的一项。每个元素应该有?相同的概率?被返回。
示例 :
输入: inputs = [“RandomizedSet”, “insert”, “remove”, “insert”, “getRandom”, “remove”, “insert”, “getRandom”] [[], [1], [2], [2], [], [1], [2], []] 输出: [null, true, false, true, 2, true, false, 2] 解释: RandomizedSet randomSet = new RandomizedSet(); // 初始化一个空的集合 randomSet.insert(1); // 向集合中插入 1 , 返回 true 表示 1 被成功地插入
randomSet.remove(2); // 返回 false,表示集合中不存在 2
randomSet.insert(2); // 向集合中插入 2 返回 true ,集合现在包含 [1,2]
randomSet.getRandom(); // getRandom 应随机返回 1 或 2
randomSet.remove(1); // 从集合中移除 1 返回 true 。集合现在包含 [2]
randomSet.insert(2); // 2 已在集合中,所以返回 false
randomSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2
java代码:
class RandomizedSet {
private HashMap<Integer,Integer> map; // 保存元素在 list 中的位置
private ArrayList<Integer> list; // 保存元素的list
private Random random; // 生成随机数
// 初始化
public RandomizedSet() {
list = new ArrayList<>();
map = new HashMap<>();
random = new Random();
}
// 插入一个元素,如果已经存在则返回 false, 如果不存在则将其插入,并返回true
public boolean insert(int val) {
if(map.containsKey(val))
return false;
// 如果元素不存在,则将其插入
list.add(val);
// 同时,将元素与对应的索引记录到 map 中
map.put(val,list.size() - 1);
return true;
}
// 删除一个元素,如果不存在这个元素则返回 false, 如果存在则将其删除,并返回true;
public boolean remove(int val) {
if(!map.containsKey(val))
return false;
// 获取待删除元素在 list 中的位置。
Integer index = map.get(val);
// 获取 list 中的最后一个元素
Integer lastEle = list.get(list.size() - 1);
// 在待删除元素的位置上,将其设置为 最后一个元素,相当于把它删除了
list.set(index, lastEle);
// 同时更新 最后一个元素 在数组中的索引映射关系
map.put(lastEle, index);
// 直接将最后一个删除(最后一个元素已经被保存在原待删除元素的位置上了)
list.remove(list.size() - 1);
// map 中也要将待删除元素的索引关系删除
map.remove(val);
return true;
}
// 随机获取一个元素
public int getRandom() {
return list.get(random.nextInt(list.size()));
}
}
|