flag
软件学院大三党,每天一道算法题,第八天
题目介绍
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。
insert(val):当元素 val 不存在时,向集合中插入该项。
remove(val):元素 val 存在时,从集合中移除该项。
getRandom():随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/insert-delete-getrandom-o1
思路
核心思路是用hashmap记录数组每个值对应的下标,在插入和删除时不需要遍历数组寻找对应的数字下标,从而实现插入O(1)。
由于删除数组中的数据不是O(1),这里将数组中待删除的数字用数组最后一个数字代替,然后size - 1,下次insert的时候将size位置的数字覆盖,从而实现O(1)删除。不影响再次删除和产生随机数。
关键代码
public class RandomizedSet {
/** Initialize your data structure here. */
Map<Integer,Integer>map;//键为value,值为index
ArrayList<Integer>list;
int size;
public RandomizedSet() {
map=new HashMap<>();
list=new ArrayList<>();
size=0;
}
/** 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;
else {
list.add(size,val);
map.put(val,size);
size++;
}
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;
else {
int endValue=list.get(size-1);//list中最后一个元素
int index=map.get(val);//val对应的索引值
list.set(index,endValue);//将此索引值对应的元素换成endvalue
map.put(endValue,index);
map.remove(val);
size--;
}
return true;
}
/** Get a random element from the set. */
public int getRandom() {
Random random=new Random();
return list.get(random.nextInt(size));//产生的随机数为0-size的整数,不包括size
}
}
测试
测试用例:
RandomizedSet randomizedSet=new RandomizedSet();
System.out.println(randomizedSet.insert(3));
System.out.println(randomizedSet.remove(4));
System.out.println(randomizedSet.insert(4));
System.out.println(randomizedSet.insert(3));
System.out.println(randomizedSet.insert(5));
System.out.println(randomizedSet.remove(5));
System.out.println(randomizedSet.getRandom());
结果:
参考资料
Java中random的用法:
https://www.cnblogs.com/ningvsban/p/3590722.html