解法一
思路
insert 和 remove 對於 HashMap 來說都只是 O(1) 的時間複雜度。但 HashMap 是無序的,需要等概率,在 O(1) 取出一個數,那麼就必須使用具有索引的 List。而對於 List, 在任意位置的 remve() 需要 O(n) 的時間複雜度,除非這個元素在 List 的末尾。這時,我們就需要將要刪除的元素放在末尾,保證 O(1) 時間複雜度。這是本題的關鍵。所以我們需要 HashMap 和 ArrayList 兩種資料結構來實現本題所需要的功能。
程式碼
class RandomizedSet {
Random random = new Random();
LinkedList<Integer> list;
HashMap<Integer, Integer> map;
/** Initialize your data structure here. */
public RandomizedSet() {
list = new LinkedList<>();
map = new HashMap<>();
}
/** 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)) {
list.add(val);
map.put(val, list.size() - 1); // <Key, Value> = <val, index of val in list>
return true;
}
return false;
}
/** 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;
}
// Move val to the end of the list, and the last element to the position of val
// Update the position of the last element in HashMap
// Then remove val
int loc = map.get(val); // position of val in list
if (loc < list.size() - 1) { // If val is not the last element
int last = list.getLast();
list.set(loc, last); // set last to the position of val
map.put(last, loc); // update the position of last in HashMap
}
map.remove(val);
list.removeLast();
return true;
}
/** Get a random element from the set. */
public int getRandom() {
int rand = random.nextInt(list.size()); // Generate a random index from [0, list.size())
return list.get(rand);
}
}
/**
* 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();
*/
複雜度分析
O(1)
Follow Up
- Insert Delete GetRandom O(1) - Duplicates allowed