本题有点类似设计题
原本想到了大体思路:
HashMap<Integer, Integer>
: key是存的val,value是ArrayList<Integer>
的indexArrayList<Integer>
: 存的是val
但是一开始没有想明白如果remove
元素的话,那么HashMap<Integer, Integer>
里存的index就都变了,在被删除的元素的后面的index都会自动往前移动1
看了答案后想明白了,可以在删除前,手动把要删除的元素移动到ArrayList<Integer>
的末尾,这样就可以避免这个问题。
- 时间复杂度:
insert()
:remove()
:getRandom()
:
- 空间复杂度:
代码如下:
class RandomizedSet {
private Map<Integer, Integer> mySet;
private List<Integer> myList;
private Random rand;
/** Initialize your data structure here. */
public RandomizedSet() {
mySet = new HashMap<>();
myList = new ArrayList<>();
rand = new Random();
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
public boolean insert(int val) {
if (mySet.containsKey(val)) {
return false;
}
myList.add(val);
mySet.put(val, myList.size() - 1);
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
if (!mySet.containsKey(val)) {
return false;
}
int oldIdx = mySet.get(val);
if (oldIdx != myList.size() - 1) {
int swapVal = myList.get(myList.size() - 1);
mySet.put(swapVal, oldIdx);
myList.set(oldIdx, swapVal);
}
mySet.remove(val);
myList.remove(myList.size() - 1);
return true;
}
/** Get a random element from the set. */
public int getRandom() {
return myList.get(rand.nextInt(myList.size()));
}
}
/**
* 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();
*/