一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
今天疫情没有那么严重了,封控的家人也能见面了
O(1) 时间插入、删除和获取随机元素
该题出自力扣的380题 —— O(1) 时间插入、删除和获取随机元素【中等题】
审题
- 该题的题意也相对比较简单,属于一道设计题
- 设计出一个函数,包含三个方法,新增、删除、随机访问
- 并且需要满足一个条件,就是每个方法的时间复杂度都为O(1)
- 根据题意,需要满足时间复杂度为O(1),则新增与删除可以考虑用Map,满足随机访问 + 时间复杂度的方法,可以考虑用数组
- 需要注意的是,HashMap,key存储值val,value存储数组的下标,对应着数组的下标存放的值val
- 构造方法:
- 初始化一个HashMap
- 初始化一个Random随机方法
- 初始化一个数组,并且给定长度为数组的最大长度2的5次方
- 定义一个下标初始值 -1
- 新增:
- 判断map是否存在val,存在直接返回false
- 存放数组,下标为初始值 +1
- 存进Map
- 删除方法:
- 因为题意规定时间复杂度要O(1),而且选用了数组,就不存在删除这个说法
- 所以就可以联想到删除链表节点 = 使指针取代它
- 把要删除的值从HashMap中remove掉
- 把当前值的下标与末尾下标对调,使末尾的值存放在当前的下标中,初始下标--
- 随机方法
- 直接调用Random方法,限制范围在index+1内
- 构造方法:
编码
class RandomizedSet {
Map<Integer,Integer> map;
int[] nums;
Random random;
int index = -1;
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet obj = new RandomizedSet();
* boolean param_1 = obj.insert(val);
* boolean param_2 = obj.remove(val);
* int param_3 = obj.getRandom();
*/
public RandomizedSet() {
map = new HashMap<>();
nums = new int[20000];
random = new Random();
}
public boolean insert(int val) {
if (map.containsKey(val))return false;
nums[++index] = val;
map.put(val,index);
return true;
}
public boolean remove(int val) {
if (!map.containsKey(val))return false;
int last = map.remove(val);
//末尾对调 + index --
if (last != index){
//不是末尾
map.put(nums[index],last);
}
nums[last] = nums[index--];
return true;
}
public int getRandom() {
return nums[random.nextInt(index +1)];
}
}