题目:
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构:
insert(val):当元素 val 不存在时返回 true ,并向集合中插入该项,否则返回 false 。
remove(val):当元素 val 存在时返回 true ,并从集合中移除该项,否则返回 false 。
getRandom:随机返回现有集合中的一项。每个元素应该有 相同的概率 被返回。
分析:
插入和删除的时间复杂度都是O(1),能够同时满足这些时间效率要求的只有哈希表,因此这个数据结构得用哈希表,但哈希表不能够满足
等概率返回数组中的,如果数值是保存在数组中的,那么很容易实现等概率返回数组中的每个数值。需要结合哈希表和数组的特性来设计这个数据容器。
import java.util.*;
class RandomizedSet {
/** Initialize your data structure here. */
Map<Integer,Integer> map;
List<Integer> list;
public RandomizedSet() {
map = new HashMap<>();
list = new ArrayList<>();
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
public boolean insert(int val) {
if (map.containsKey(val)){
return false;
}
// 如果没有val值,把它添加到数组nums的尾部,并把它和数组中的下标添加到哈希表中
map.put(val,list.size());
list.add(val);
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
if (!map.containsKey(val)){
return false;
}
// 在哈希表中得到待删除的下标
int location = map.get(val);
// 为了避免在数组中删除数字的时候移动数据,可以把被删除的数字和数组尾部的数字进行交换,再删除数组最后的数字
// 这样就可以不引起数据移动。
map.put(list.get(list.size()-1),location);
map.remove(val);
// 将指定索引处的元素替换成指定的元素
list.set(location,list.get(list.size()-1));
list.remove(list.size()-1);
return true;
}
/** Get a random element from the set. */
public int getRandom() {
Random random = new Random();
int index = random.nextInt(list.size());
return list.get(index);
}
}