设计一个generic class,要求支持add(T), remove(T), randomRemove(T)三个操作,并且必须保证都是O(1)。比如说add(cat), add(dog), add(pig), add(cat), remove(cat), remove(dog)等等,她还特意说必须要考虑重复,也就是说删掉一个cat后另一个cat必须还在,而且randomRemove()必须保证所有元素被删掉的概率均等。
解法一:
所以这题应该是用第一个HashMap放index + 元素内容,重复的元素要分开放,第二个HashMap放元素内容+arrayList of indexes,把重复元素的indexes放在一起。所以上面的例子就应该是HashMap1 : (1, cat), (2, dog), (3, pig), (4, cat), HashMap2: (cat, (1, 4)), (dog, 2), (pig, 3)这样。add, remove很容易O(1),randomRemove()时生成一个1-4的随机数,比如2,然后从第一个map里找2对应的是dog,然后从第二个HashMap里找到dog,把dog删掉。但有一个小问题我觉得她自己也没想清楚,就是如果有很多dog,那么dog的list很长,并不能保证O(1)找到要删的那个dog的index吧?。。另外还有一个trick,就是删掉dog后,要用第一个map中的最后一个元素去填补中间的gap,否则下次如果再生成随机数2,就找不到元素了。
解法二:
/* Java program to design a data structure that support folloiwng operations in Theta(n) time a) Insert b) Delete c) Search d) getRandom */ import java.util.*; // class to represent the required data structure class MyDS { ArrayList<Integer> arr; // A resizable array // A hash where keys are array elements and vlaues are // indexes in arr[] HashMap<Integer, Integer> hash; // Constructor (creates arr[] and hash) public MyDS() { arr = new ArrayList<Integer>(); hash = new HashMap<Integer, Integer>(); } // A Theta(1) function to add an element to MyDS // data structure void add(int x) { // If ekement is already present, then noting to do if (hash.get(x) != null) return; // Else put element at the end of arr[] int s = arr.size(); arr.add(x); // And put in hash also hash.put(x, s); } // A Theta(1) function to remove an element from MyDS // data structure void remove(int x) { // Check if element is present Integer index = hash.get(x); if (index == null) return; // If present, then remove element from hash hash.remove(x); // Swap element with last element so that remove from // arr[] can be done in O(1) time int size = arr.size(); Integer last = arr.get(size-1); Collections.swap(arr, index, size-1); // Remove last element (This is O(1)) arr.remove(size-1); // Update hash table for new index of last element hash.put(last, index); } // Returns a random element from MyDS int getRandom() { // Find a random index from 0 to size - 1 Random rand = new Random(); // Choose a different seed int index = rand.nextInt(arr.size()); // Return element at randomly picked index return arr.get(index); } // Returns index of element if element is present, otherwise null Integer search(int x) { return hash.get(x); } } // Driver class class Main { public static void main (String[] args) { MyDS ds = new MyDS(); ds.add(10); ds.add(20); ds.add(30); ds.add(40); System.out.println(ds.search(30)); ds.remove(20); ds.add(50); System.out.println(ds.search(50)); System.out.println(ds.getRandom()); } }
reference:
http://www.geeksforgeeks.org/design-a-data-structure-that-supports-insert-delete-search-and-getrandom-in-constant-time/