Design a data structure that supports insert, delete, search and getRandom in constant time - GeeksforGeeks

18 May, 2021
Design a data structure that supports the following operations in Θ(1) time.insert(x): Inserts an item x to the data structure if not already present.remove(x): Removes item x from the data structure if present. search(x): Searches an item x in the data structure.getRandom(): Returns a random element from current set of elements  
We can use hashing to support first 3 operations in Θ(1) time. How to do the 4th operation? The idea is to use a resizable array (ArrayList in Java, vector in C) together with hashing. Resizable arrays support insert in Θ(1) amortized time complexity. To implement getRandom(), we can simply pick a random number from 0 to size-1 (size is the number of current elements) and return the element at that index. The hash map stores array values as keys and array indexes as values.Following are detailed operations.insert(x) 1) Check if x is already present by doing a hash map lookup. 2) If not present, then insert it at the end of the array. 3) Add in the hash table also, x is added as key and last array index as the index.remove(x) 1) Check if x is present by doing a hash map lookup. 2) If present, then find its index and remove it from a hash map. 3) Swap the last element with this element in an array and remove the last element. Swapping is done because the last element can be removed in O(1) time. 4) Update index of the last element in a hash map.getRandom() 1) Generate a random number from 0 to last index. 2) Return the array element at the randomly generated index.search(x) Do a lookup for x in hash map.Below is the implementation of the data structure. 
C++
Java
Python3
/* C++ program to design a DS that supports following operationsin Theta(n) timea) Insertb) Deletec) Searchd) getRandom */ #include<bits/stdc++.h>using namespace std; // class to represent the required data structureclass myStructure{    // A resizable array    vector <int> arr;         // A hash where keys are array elements and values are    // indexes in arr[]    map <int, int> Map;     public:    // A Theta(1) function to add an element to MyDS    // data structure    void add(int x)    {        // If element is already present, then nothing to do        if(Map.find(x) != Map.end())            return;                     // Else put element at the end of arr[]        int index = arr.size();        arr.push_back(x);                     // and hashmap also        Map.insert(std::pair<int,int>(x, index));    }             // function to remove a number to DS in O(1)    void remove(int x)    {        // element not found then return        if(Map.find(x) == Map.end())            return;                     // remove element from map        int index = Map.at(x);        Map.erase(x);                     // swap with last element in arr        // then remove element at back        int last = arr.size() - 1;        swap(arr[index], arr[last]);        arr.pop_back();                     // Update hash table for new index of last element        Map.at(arr[index]) = index;    }             // Returns index of element if element is present, otherwise null    int search(int x)    {        if(Map.find(x) != Map.end())        return Map.at(x);        return -1;    }             // Returns a random element from myStructure    int getRandom()    {        // Find a random index from 0 to size - 1        srand (time(NULL));        int random_index = rand() % arr.size();                     // Return element at randomly picked index        return arr.at(random_index);    }    }; // Driver mainint main(){    myStructure ds;    ds.add(10);    ds.add(20);    ds.add(30);    ds.add(40);    cout << ds.search(30) << endl;    ds.remove(20);    ds.add(50);    cout << ds.search(50) << endl;    cout << ds.getRandom() << endl;} // This code is contributed by Aditi Sharma
/* Java program to design a data structure that support following operations   in Theta(n) time   a) Insert   b) Delete   c) Search   d) getRandom */import java.util.*; // class to represent the required data structureclass MyDS{   ArrayList<Integer> arr;   // A resizable array    // A hash where keys are array elements and values 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 element is already present, then nothing 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 classclass 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());    }}
'''Python program to design a DS thatsupports following operationsin Theta(n) time:a) Insertb) Deletec) Searchd) getRandom'''import random # Class to represent the required# data structureclass MyDS:     # Constructor (creates a list and a hash)    def __init__(self):                 # A resizable array        self.arr = []         # A hash where keys are lists elements        # and values are indexes of the list        self.hashd = {}     # A Theta(1) function to add an element    # to MyDS data structure    def add(self, x):                 # If element is already present,        # then nothing has to be done        if x in self.hashd:            return         # Else put element at        # the end of the list        s = len(self.arr)        self.arr.append(x)         # Also put it into hash        self.hashd[x] = s     # A Theta(1) function to remove an element    # from MyDS data structure    def remove(self, x):                 # Check if element is present        index = self.hashd.get(x, None)        if index == None:            return         # If present, then remove        # element from hash        del self.hashd[x]         # Swap element with last element        # so that removal from the list        # can be done in O(1) time        size = len(self.arr)        last = self.arr[size - 1]        self.arr[index], \        self.arr[size - 1] = self.arr[size - 1], \                             self.arr[index]         # Remove last element (This is O(1))        del self.arr[-1]         # Update hash table for        # new index of last element        self.hashd[last] = index     # Returns a random element from MyDS    def getRandom(self):                          # Find a random index from 0 to size - 1        index = random.randrange(0, len(self.arr))         # Return element at randomly picked index        return self.arr[index]     # Returns index of element    # if element is present,    # otherwise none    def search(self, x):        return self.hashd.get(x, None) # Driver Codeif __name__=="__main__":    ds = MyDS()    ds.add(10)    ds.add(20)    ds.add(30)    ds.add(40)    print(ds.search(30))    ds.remove(20)    ds.add(50)    print(ds.search(50))    print(ds.getRandom()) # This code is contributed# by Saurabh Singh
Output:  
2
3
40
This article is contributed by Manish Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
SwapnilShukla1
ssaurabhh4
dhyey35
simmytarika5
Amazon
Advanced Data Structure
Hash
Amazon
Hash
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Agents in Artificial Intelligence
Decision Tree Introduction with example
Disjoint Set Data Structures
AVL Tree | Set 2 (Deletion)
Red-Black Tree | Set 2 (Insert)
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)
Count pairs with given sum