题目地址:
https://www.lintcode.com/problem/insert-delete-getrandom-o1/description
设计一个数据结构,要求在
O
(
1
)
O(1)
O(1)时间内能进行如下操作:
1、插入一个数字(如果该数字已存在,则不插入);
2、删除一个数字;
3、随机返回存储在该数据结构中的数字,要求每个数字取出的概率均等。
思路是,用一个list存数字,用一个map存每个数字对应的下标。这样在插入的时候,先check一下数字是否在map里,如果不在,则插入到list末尾,并且将数字及其下标存进map;删除的时候可以先在map里查一下是否存在,存在的时候,为了实现 O ( 1 ) O(1) O(1)时间内删除,我们可以将要删除的数字移到list末尾再删除,但同时要注意修改一下移动到前面去的数字的下标;getRandom的实现要依赖java的Random类,产生一个随机数作为下标,从list中取出数字返回即可。代码如下:
import java.util.*;
public class RandomizedSet {
private List<Integer> list;
private Map<Integer, Integer> map;
private Random random;
public RandomizedSet() {
// do intialization if necessary
list = new ArrayList<>();
map = new HashMap<>();
random = new Random();
}
/*
* @param val: a value to the set
* @return: true if the set did not already contain the specified element or false
*/
public boolean insert(int val) {
// write your code here
if (map.containsKey(val)) {
return false;
}
map.put(val, list.size());
list.add(val);
return true;
}
/*
* @param val: a value from the set
* @return: true if the set contained the specified element or false
*/
public boolean remove(int val) {
// write your code here
if (!map.containsKey(val)) {
return false;
}
int idx = map.get(val);
// 如果不在末尾,就将其换到末尾
if (idx != list.size() - 1) {
Collections.swap(list, idx, list.size() - 1);
map.put(list.get(idx), idx);
}
list.remove(list.size() - 1);
return true;
}
/*
* @return: Get a random element from the set
*/
public int getRandom() {
// write your code here
int ranIdx = random.nextInt(list.size());
return list.get(ranIdx);
}
}
所有操作时间复杂度 O ( 1 ) O(1) O(1),空间 O ( n ) O(n) O(n)。