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

Design a data structure that supports following operations in Θ(1) time.

insert(x): Inserts an item x to the data structure if not already present.

remove(x): Removes an 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 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 hash table also, x is added as key and last array index as 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 hash map.
3) Swap the last element with this element in array and remove the last element.
Swapping is done because the last element can be removed in O(1) time.
4) Update index of last element in 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 implementation of the data structure.

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

/* 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());
    }
}

chevron_right


C++

filter_none

edit
close

play_arrow

link
brightness_4
code

/* C++ program to design a DS that supports folloiwng operations
in Theta(n) time
a) Insert
b) Delete
c) Search
d) getRandom */
  
#include<bits/stdc++.h>
using namespace std;
  
// class to represent the required data structure
class myStructure
{
    // A resizable array
    vector <int> arr;
      
    // A hash where keys are array elements and vlaues 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 ekement is already present, then noting 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 main
int 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

chevron_right



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



My Personal Notes arrow_drop_up

Improved By : SwapnilShukla1



Article Tags :
Practice Tags :


7


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.