*Add, Remove and randomRemove in O(1)

设计一个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/

原文地址:https://www.cnblogs.com/hygeia/p/5156453.html