381. O(1) 时间插入、删除和获取随机元素 - 允许重复
381. O(1) 时间插入、删除和获取随机元素 - 允许重复
LeetCode_381
题目详情
题解分析
代码实现
package com.walegarrett.interview;
import java.util.*;
/**
* @Author WaleGarrett
* @Date 2021/2/28 22:23
*/
/**
* 题目详情:设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。
* 注意: 允许出现重复元素。
* insert(val):向集合中插入元素 val。
* remove(val):当 val 存在时,从集合中移除一个 val。
* getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
*/
public class LeetCode_381 {
List<Integer> list;//存储所有元素
HashMap<Integer, Set<Integer>> map;//存储相同元素在list中的下标
/** Initialize your data structure here. */
public LeetCode_381() {
list = new ArrayList<>();
map = new HashMap<>();
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
public boolean insert(int val) {
list.add(val);
Set<Integer> set = map.getOrDefault(val, new HashSet<Integer>());
set.add(list.size()-1);//将val在list中的下标信息存入set中
map.put(val, set);
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))
return false;
Iterator<Integer> it = map.get(val).iterator();
int index = it.next();//获取待删除元素在map中的下标
//获取list中的最后一个元素
int last = list.get(list.size()-1);
//将list中的index位置的数字变成last
list.set(index, last);
//删除map中val和last的位置信息
map.get(val).remove(index);
map.get(last).remove(list.size()-1);
//将新的位置信息加入到last中
if(index < list.size()-1){
map.get(last).add(index);
}
//如果删除val后list中不存在该元素,则需要从map中移除
if(map.get(val).size() == 0){
map.remove(val);
}
//将调到最后的元素删除
list.remove(list.size()-1);
return true;
}
/** Get a random element from the collection. */
public int getRandom() {
int len = list.size();
return list.get((int)(Math.random() * len));
}
}
Either Excellent or Rusty