381. [雜湊表]O(1) 時間插入、刪除和獲取隨機元素 - 允許重複
阿新 • • 發佈:2020-11-01
381. O(1) 時間插入、刪除和獲取隨機元素 - 允許重複
方法一:雜湊表
由於\(List\)無法直接在\(O(1)\)的時間複雜度查詢元素值,所以可以考慮\(List\)和\(HashMap\)聯合使用,\(HashMap\)讓\(HashMap\)記錄值和索引。考慮到一個值不會有2個相同索引,並且在刪除交換等操作時需要對值得索引也進行刪除等操作,所以索引的部分只需要再額外使用一個\(Set\)完成插入、刪除數字的下標即可。
由於\(List\)只有在刪除尾元素時,才是以\(O(1)\)的時間複雜度完成的,做法可以是先把需要刪除的元素與最後一個元素交換,在刪除最後一個元素。具體實現如下。
// 執行用時: 14 ms , 在所有 Java 提交中擊敗了 91.73% 的使用者 // 記憶體消耗: 45.3 MB , 在所有 Java 提交中擊敗了 56.87% 的使用者 class RandomizedCollection { int n ;//當前集合大小 HashMap<Integer,Set<Integer>>map; ArrayList<Integer>list; Random random; /** Initialize your data structure here. */ public RandomizedCollection() { this.random = new Random(); this.map = new HashMap(); this.n = 0; this.list = new ArrayList<>(); } /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ public boolean insert(int val) { Set set = map.get(val); if(set==null) set = new HashSet<>(); set.add(n);//新增索引 list.add(val); map.put(val, set); n++; return set.size()==1; } /** Removes a value from the collection. Returns true if the collection contained the specified element. */ public boolean remove(int val) { if(map.containsKey(val)){ int lastIndex = n-1;//得到最後2個值索引 Set lastset = map.get(list.get(lastIndex)); Set set = map.get(val); int currIndex = (int)set.iterator().next();//得到當前值索引 //進行刪除操作 swap(list, currIndex, lastIndex); list.remove(n-1);//將其在列表中刪除 set.remove(currIndex);//刪除原值 if(set.size()==0) map.remove(val);//在圖中刪除 //修改最後一個值的索引 lastset.remove(n-1); lastset.add(currIndex); n--; }else{ return false; } return true; } /** Get a random element from the collection. */ public int getRandom() { return list.get(random.nextInt(n)); } private void swap(List<Integer> list ,int i,int j){ int temp = list.get(i); list.set(i, list.get(j)); list.set(j, temp); } } /** * Your RandomizedCollection object will be instantiated and called as such: * RandomizedCollection obj = new RandomizedCollection(); * boolean param_1 = obj.insert(val); * boolean param_2 = obj.remove(val); * int param_3 = obj.getRandom(); */