381. [哈希表]O(1) 时间插入、删除和获取随机元素 - 允许重复
381. O(1) 时间插入、删除和获取随机元素 - 允许重复
方法一:哈希表
由于\(List\)无法直接在\(O(1)\)的时间复杂度查找元素值,所以可以考虑\(List\)和\(HashMap\)联合使用,\(HashMap\)让\(HashMap\)记录值和索引。考虑到一个值不会有2个相同索引,并且在删除交换等操作时需要对值得索引也进行删除等操作,所以索引的部分只需要再额外使用一个\(Set\)完成插入、删除数字的下标即可。
由于\(List\)只有在删除尾元素时,才是以\(O(1)\)的时间复杂度完成的,做法可以是先把需要删除的元素与最后一个元素交换,在删除最后一个元素。具体实现如下。
// 执行用时: 14 ms , 在所有 Java 提交中击败了 91.73% 的用户
// 内存消耗: 45.3 MB , 在所有 Java 提交中击败了 56.87% 的用户
class RandomizedCollection {
int n ;//当前集合大小
HashMap<Integer,Set<Integer>>map;
ArrayList<Integer>list;
Random random;
/** Initialize your data structure here. */
public RandomizedCollection() {
this.random = new Random();
this.map = new HashMap();
this.n = 0;
this.list = new ArrayList<>();
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
public boolean insert(int val) {
Set set = map.get(val);
if(set==null) set = new HashSet<>();
set.add(n);//添加索引
list.add(val);
map.put(val, set);
n++;
return set.size()==1;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
public boolean remove(int val) {
if(map.containsKey(val)){
int lastIndex = n-1;//得到最后2个值索引
Set lastset = map.get(list.get(lastIndex));
Set set = map.get(val);
int currIndex = (int)set.iterator().next();//得到当前值索引
//进行删除操作
swap(list, currIndex, lastIndex);
list.remove(n-1);//将其在列表中删除
set.remove(currIndex);//删除原值
if(set.size()==0) map.remove(val);//在图中删除
//修改最后一个值的索引
lastset.remove(n-1);
lastset.add(currIndex);
n--;
}else{
return false;
}
return true;
}
/** Get a random element from the collection. */
public int getRandom() {
return list.get(random.nextInt(n));
}
private void swap(List<Integer> list ,int i,int j){
int temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
/**
* Your RandomizedCollection object will be instantiated and called as such:
* RandomizedCollection obj = new RandomizedCollection();
* boolean param_1 = obj.insert(val);
* boolean param_2 = obj.remove(val);
* int param_3 = obj.getRandom();
*/

浙公网安备 33010602011771号