1. 程式人生 > >[leetcode]380. Insert Delete GetRandom O(1)設計數據結構,實現存,刪,隨機取的時間復雜度為O(1)

[leetcode]380. Insert Delete GetRandom O(1)設計數據結構,實現存,刪,隨機取的時間復雜度為O(1)

println exist rand and 進行 pro 時間復雜度 sig was

題目:

Design a data structure that supports all following operations in average O(1) time.

1.insert(val): Inserts an item val to the set if not already present.
2.remove(val): Removes an item val from the set if present.
3.getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
Example:

// Init an empty set.
RandomizedSet randomSet = new RandomizedSet();

// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1);

// Returns false as 2 does not exist in the set.
randomSet.remove(2);

// Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2);

// getRandom should return either 1 or 2 randomly.
randomSet.getRandom();

// Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1);

// 2 was already in the set, so return false.
randomSet.insert(2);

// Since 2 is the only number in the set, getRandom always return 2.
randomSet.getRandom();
思路:肯定是借助java已有的數據結構進行設計,常用的有ArrayList,HashMap,HashSet,能做到隨機取數的有前兩個,能實現判斷和刪除O(1)是否包含的是後兩個,
而且map想判斷的話,數據必須存key,這樣就不能取數了。用list取數的時候,必須要知道數據和下標的對應關系,所以可以map和list配合
 1 * 沒有一個現成的數據結構可以符合要求,但是可以組合使用它們實現,list存數據,map的key存數據,value存數據在list中的下標,
 2 * 這樣ArrayList可以實現存O(1),刪除借助map獲取下標,實現O(1),判斷重復用map的containsKey方法
 3 * 其實insert和remove,map都可以單獨實現O(1),不單獨用map就是因為無法實現getRandom,因為由於判斷重復需要containsKey方法,所以數據必須存key而不是value
 4 * 但是隨機取數時,map無法取出指定key,所以不能單獨用map,隨機取數只能用list,隨機指定下標而取出數值
5 * getRandom要求知道數據結構的大小,並且存儲元素是相鄰的 6 public static void main(String[] args) { 7 Q380InsertDeleteGetRandomO1 q = new Q380InsertDeleteGetRandomO1(); 8 q.set.insert(0); 9 q.set.insert(1); 10 q.set.remove(0); 11 System.out.println(q.set.list); 12 System.out.println(q.set.map);
13 System.out.println(q.set.getRandom()); 14 } 15 class RandomizedSet { 16 HashMap<Integer,Integer> map; 17 ArrayList<Integer> list; 18 /** Initialize your data structure here. */ 19 public RandomizedSet() { 20 map = new HashMap(); 21 list = new ArrayList<>(); 22 } 23 24 /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ 25 public boolean insert(int val) { 26 //判斷是否包含可以用map或者set,但是set不能存下標 27 if (!map.containsKey(val)) 28 { 29 //key存數據,value存它在list中的下標 30 map.put(val,list.size()); 31 list.add(val); 32 return true; 33 } 34 else 35 return false; 36 } 37 38 /** Removes a value from the set. Returns true if the set contained the specified element. */ 39 public boolean remove(int val) { 40 if (map.containsKey(val)) 41 { 42 //刪除:要想map中的value不用全部變,只能刪除的時候list的下標不全部改變(list默認刪除後後邊的元素會向前挪),多以采取的方法: 43 //先把list最後一個元素num覆蓋到指定位置(借助map獲取位置),再刪除最後一個元素,然後map修改num的value,再刪除val那條數據 44 //最後一個元素 45 int num = list.get(list.size()-1); 46 //覆蓋(也可以兩個元素交換) 47 list.set(map.get(val),num); 48 //刪除最後一個元素 49 list.remove(list.size()-1); 50 //改變num的下標 51 map.put(num,map.get(val)); 52 //刪除val這條數據 53 map.remove(val); 54 return true; 55 } 56 else 57 return false; 58 } 59 60 /** Get a random element from the set. */ 61 public int getRandom() { 62 Random random = new Random(); 63 //隨機獲取下標進行取數 64 return list.get(random.nextInt(list.size())); 65 } 66 } 67 68 /** 69 * Your RandomizedSet object will be instantiated and called as such: 70 * RandomizedSet obj = new RandomizedSet(); 71 * boolean param_1 = obj.insert(val); 72 * boolean param_2 = obj.remove(val); 73 * int param_3 = obj.getRandom(); 74 */

map和set可不可以組合呢,想了想好像也可以,set只負責判斷包含,map的存,刪,隨機取,都可以O(1),有待驗證

[leetcode]380. Insert Delete GetRandom O(1)設計數據結構,實現存,刪,隨機取的時間復雜度為O(1)