LeetCode - 381. Insert Delete GetRandom O(1) - Duplicates allowed(允許重複)
阿新 • • 發佈:2019-01-13
LeetCode - 381. Insert Delete GetRandom O(1) - Duplicates allowed(允許重複)
題目連結
題目
解析
做這題之前先做LeetCode - 380。
這一題加上了可以加入重複的元素,題目就變得複雜了一些。
- 大體思路還是使用
HashMap + ArrayList
,只不過Map
是HashMap<Integer, ArrayList<Integer>>
的形式,而List
則是ArrayList<int[]>
形式; - 其中
Map
的key
存的是值val
,而對應的value
List
中值是val
的下標的集合; List
中每個位置也要存兩個資訊,一個是值val
(陣列[0]
位置),另一個存這個值val
在map
中的下標集合中的位置(陣列[1]
位置);
下圖展示了儲存
容器中有2
個6
、1
個8
、2
個9
。
新增元素很簡單,維護map
和list
即可。
例如新增元素6
:
刪除元素思想也是和最後一個元素交換位置,不過也要維護相應的資訊即可。
刪除元素9
:
class RandomizedCollection {
private HashMap<Integer, ArrayList<Integer> >valIndexsMap;
private ArrayList<int[]> vals; // store the position in the map's value
public RandomizedCollection() {
valIndexsMap = new HashMap<>();
vals = new ArrayList<>();
}
public boolean insert(int val) {
boolean contain = !valIndexsMap. containsKey(val);
// ArrayList<Integer>indexs = valIndexsMap.get(val);
// if(indexs == null){
// indexs = new ArrayList<>();
// }
// indexs.add(vals.size());
ArrayList<Integer>indexs = valIndexsMap.computeIfAbsent(val, k -> new ArrayList<>());
indexs.add(vals.size());
vals.add(new int[]{val, indexs.size()-1});
return contain;
}
public boolean remove(int val) {
if(!valIndexsMap.containsKey(val))
return false;
ArrayList<Integer>indexs = valIndexsMap.get(val);
int removeIndex = indexs.get(indexs.size() - 1);
indexs.remove(indexs.size()-1);
if(indexs.isEmpty())
valIndexsMap.remove(val);
if(removeIndex < vals.size()-1){ // exchange
// 將最後一個元素放在 removeIndex位置
vals.get(removeIndex)[0] = vals.get(vals.size()-1)[0];
vals.get(removeIndex)[1] = vals.get(vals.size()-1)[1];
valIndexsMap.get(vals.get(removeIndex)[0]).set(vals.get(removeIndex)[1], removeIndex);
}
vals.remove(vals.size()-1);
return true;
}
public int getRandom() {
return vals.get((int)(Math.random() * vals.size()))[0];
}
}
這裡注意Java8
中computeIfAbsent
用法:
類似下面的用法
Object key = map.get("key");
if (key == null) {
key = new Object();
map.put("key", key);
}
//上面的操作可以簡化為一行,若key對應的value為空,會將第二個引數的返回值存入並返回
Object key2 = map.computeIfAbsent("key", k -> new Object());
具體用法舉例:
import java.util.*;
public class Test {
public static void main(String[] args){
Map<String, List<String>> map = new HashMap<>();
List<String> list;
list = map.get("list-1");
if (list == null) {
list = new LinkedList<>();
map.put("list-1", list);
}
list.add("one");
//使用 computeIfAbsent 可以這樣寫
list = map.computeIfAbsent("list-1", k -> new ArrayList<>());
list.add("one");
}
}