Implement the RandomizedSet
class:
RandomizedSet()
Initializes theRandomizedSet
object.bool insert(int val)
Inserts an itemval
into the set if not present. Returnstrue
if the item was not present,false
otherwise.bool remove(int val)
Removes an itemval
from the set if present. Returnstrue
if the item was present,false
otherwise.int getRandom()
Returns a random element from the current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the same probability of being returned.
You must implement the functions of the class such that each function works in average O(1)
time complexity.
Example 1:
Input ["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"] [[], [1], [2], [2], [], [1], [2], []] Output [null, true, false, true, 2, true, false, 2] Explanation RandomizedSet randomizedSet = new RandomizedSet(); randomizedSet.insert(1); // Inserts 1 to the set. Returns true as 1 was inserted successfully. randomizedSet.remove(2); // Returns false as 2 does not exist in the set. randomizedSet.insert(2); // Inserts 2 to the set, returns true. Set now contains [1,2]. randomizedSet.getRandom(); // getRandom() should return either 1 or 2 randomly. randomizedSet.remove(1); // Removes 1 from the set, returns true. Set now contains [2]. randomizedSet.insert(2); // 2 was already in the set, so return false. randomizedSet.getRandom(); // Since 2 is the only number in the set, getRandom() will always return 2.
Constraints:
-231 <= val <= 231 - 1
- At most
2 *
105
calls will be made toinsert
,remove
, andgetRandom
. - There will be at least one element in the data structure when
getRandom
is called.
这题让你实现一个random set,其实本质就是让你能在一个set里return一个random number in the set。要求时间复杂度为O(1)。
很容易能想到就是至少要定义一个hashset,正常insert / remove,然后再搞一个random number generator每次generate一个random number。但是怎么把random number对应到set里的值呢,很容易能想到那就把set里的值每个assing一个index,generate一个random index然后return它对应的set的值就好了。那怎么才能知道这个set里的值对应的index呢,那就把hashset变成hashmap,记录val -> index就行了。
那么问题来了,remove的时候还得remove from list,这会导致在除了remove最后一个元素以外的其他时候都是O(n)复杂度。这时候用的trick就是我们把remove的数字和最后一个数字交换一下,然后remove最后一个,就能保证O(1)的复杂度了,毕竟咱也不care这个list里的顺序。代码写起来还算比较简单吧,没啥坑。
class RandomizedSet {
private Map<Integer, Integer> valToIndex;
private List<Integer> list;
private Random rand = new Random();
public RandomizedSet() {
valToIndex = new HashMap<>();
list = new ArrayList<>();
}
public boolean insert(int val) {
if (valToIndex.containsKey(val)) {
return false;
}
valToIndex.put(val, list.size());
list.add(val);
return true;
}
public boolean remove(int val) {
if (!valToIndex.containsKey(val)) {
return false;
}
int index = valToIndex.get(val);
if (index != list.size() - 1) {
int lastVal = list.get(list.size() - 1);
list.set(index, lastVal);
valToIndex.put(lastVal, index);
}
list.remove(list.size() - 1);
valToIndex.remove(val);
return true;
}
public int getRandom() {
int nextRand = rand.nextInt(list.size());
return list.get(nextRand);
}
}
/**
* 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();
*/