GFG App
Open App
Browser
Continue

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

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++

 `/* C++ program to design a DS that supports following operations` `in Theta(n) time` `a) Insert` `b) Delete` `c) Search` `d) getRandom */`   `#include` `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 values are` `    ``// indexes in arr[]` `    ``unordered_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 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`

## Java

 `import` `java.util.ArrayList;` `import` `java.util.HashMap;` `import` `java.util.Map;` `import` `java.util.Random;`   `public` `class` `MyStructure {`   `    ``private` `ArrayList arr; ``// A resizable array to hold the elements` `    ``private` `Map map; ``// A hash map to store the indexes of elements in arr`   `    ``// Constructor to initialize the array and hash map` `    ``public` `MyStructure() {` `        ``arr = ``new` `ArrayList();` `        ``map = ``new` `HashMap();` `    ``}`   `    ``// Method to add an element to the data structure` `    ``public` `void` `add(``int` `x) {` `        ``// If element is already present, do nothing` `        ``if` `(!map.containsKey(x)) {` `            ``// Else add element to the end of the array` `            ``int` `index = arr.size();` `            ``arr.add(x);` `            ``// And store its index in the hash map` `            ``map.put(x, index);` `        ``}` `    ``}`   `    ``// Method to remove an element from the data structure` `    ``public` `void` `remove(``int` `x) {` `        ``// If element is not present, do nothing` `        ``if` `(map.containsKey(x)) {` `            ``// Else remove element from the hash map and get its index in the array` `            ``int` `index = map.get(x);` `            ``map.remove(x);` `            ``// Swap the element with the last element in the array and remove the last element` `            ``int` `last = arr.size() - ``1``;` `            ``arr.set(index, arr.get(last));` `            ``arr.remove(last);` `            ``// Update the hash map with the new index of the element that was swapped with the last element` `            ``map.put(arr.get(index), index);` `        ``}` `    ``}`   `    ``// Method to search for an element in the data structure` `    ``public` `int` `search(``int` `x) {` `        ``// If element is present, return its index in the array from the hash map` `        ``if` `(map.containsKey(x)) {` `            ``return` `map.get(x);` `        ``}` `        ``// Else return -1` `        ``return` `-``1``;` `    ``}`   `    ``// Method to get a random element from the data structure` `    ``public` `int` `getRandom() {` `        ``Random rand = ``new` `Random();` `        ``// Generate a random index from 0 to size - 1 of the array` `        ``int` `randomIndex = rand.nextInt(arr.size());` `        ``// Return the element at the randomly picked index` `        ``return` `arr.get(randomIndex);` `    ``}`   `    ``// Main method to test the data structure` `    ``public` `static` `void` `main(String[] args) {` `        ``MyStructure ds = ``new` `MyStructure();` `        ``ds.add(``10``);` `        ``ds.add(``20``);` `        ``ds.add(``30``);` `        ``ds.add(``40``);` `        ``System.out.println(ds.search(``30``)); ``// Output: 2` `        ``ds.remove(``20``);` `        ``ds.add(``50``);` `        ``System.out.println(ds.search(``50``)); ``// Output: 3` `        ``System.out.println(ds.getRandom()); ``// Output: A random element from the array` `    ``}` `}` `// This code is contributed by lakshyadeeppatel`

## Python3

 `'''` `Python program to design a DS that ` `supports following operations` `in Theta(n) time:` `a) Insert` `b) Delete` `c) Search` `d) getRandom` `'''` `import` `random`   `# Class to represent the required ` `# data structure ` `class` `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 Code` `if` `__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`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `MyStructure` `{`   `  ``private` `List<``int``> arr; ``// A resizable array to hold the elements` `  ``private` `Dictionary<``int``, ``int``> map; ``// A hash map to store the indexes of elements in arr`   `  ``// Constructor to initialize the array and hash map` `  ``public` `MyStructure()` `  ``{` `    ``arr = ``new` `List<``int``>();` `    ``map = ``new` `Dictionary<``int``, ``int``>();` `  ``}`   `  ``// Method to add an element to the data structure` `  ``public` `void` `add(``int` `x)` `  ``{` `    ``// If element is already present, do nothing` `    ``if` `(!map.ContainsKey(x))` `    ``{` `      ``// Else add element to the end of the array` `      ``int` `index = arr.Count;` `      ``arr.Add(x);` `      ``// And store its index in the hash map` `      ``map.Add(x, index);` `    ``}` `  ``}`   `  ``// Method to remove an element from the data structure` `  ``public` `void` `remove(``int` `x)` `  ``{` `    ``// If element is not present, do nothing` `    ``if` `(map.ContainsKey(x))` `    ``{` `      ``// Else remove element from the hash map and get its index in the array` `      ``int` `index = map[x];` `      ``map.Remove(x);` `      ``// Swap the element with the last element in the array and remove the last element` `      ``int` `last = arr.Count - 1;` `      ``arr[index] = arr[last];` `      ``arr.RemoveAt(last);` `      ``// Update the hash map with the new index of the element that was swapped with the last element` `      ``map[arr[index]] = index;` `    ``}` `  ``}`   `  ``// Method to search for an element in the data structure` `  ``public` `int` `search(``int` `x)` `  ``{` `    ``// If element is present, return its index in the array from the hash map` `    ``if` `(map.ContainsKey(x))` `    ``{` `      ``return` `map[x];` `    ``}` `    ``// Else return -1` `    ``return` `-1;` `  ``}`   `  ``// Method to get a random element from the data structure` `  ``public` `int` `getRandom()` `  ``{` `    ``Random rand = ``new` `Random();` `    ``// Generate a random index from 0 to size - 1 of the array` `    ``int` `randomIndex = rand.Next(arr.Count);` `    ``// Return the element at the randomly picked index` `    ``return` `arr[randomIndex];` `  ``}`   `  ``// Main method to test the data structure` `  ``public` `static` `void` `Main(``string``[] args)` `  ``{` `    ``MyStructure ds = ``new` `MyStructure();` `    ``ds.add(10);` `    ``ds.add(20);` `    ``ds.add(30);` `    ``ds.add(40);` `    ``Console.WriteLine(ds.search(30)); ``// Output: 2` `    ``ds.remove(20);` `    ``ds.add(50);` `    ``Console.WriteLine(ds.search(50)); ``// Output: 3` `    ``Console.WriteLine(ds.getRandom()); ``// Output: A random element from the array` `  ``}` `}`   `// This code is contributed by akashish__`

## Javascript

 `class myStructure {` `  ``constructor() {` `    ``this``.arr = [];` `    ``this``.Map = ``new` `Map();` `  ``}`   `  ``add(x) {` `    ``if` `(``this``.Map.has(x)) ``return``;` `    ``let index = ``this``.arr.length;` `    ``this``.arr.push(x);` `    ``this``.Map.set(x, index);` `  ``}`   `  ``remove(x) {` `    ``if` `(!``this``.Map.has(x)) ``return``;` `    ``let index = ``this``.Map.get(x);` `    ``this``.Map.``delete``(x);` `    ``let last = ``this``.arr.length - 1;` `    ``[``this``.arr[index], ``this``.arr[last]] = [``this``.arr[last], ``this``.arr[index]];` `    ``this``.arr.pop();` `    ``this``.Map.set(``this``.arr[index], index);` `  ``}`   `  ``search(x) {` `    ``return` `this``.Map.has(x) ? ``this``.Map.get(x) : -1;` `  ``}`   `  ``getRandom() {` `    ``let randomIndex = Math.floor(Math.random() * ``this``.arr.length);` `    ``return` `this``.arr[randomIndex];` `  ``}` `}`   `let ds = ``new` `myStructure();` `ds.add(10);` `ds.add(20);` `ds.add(30);` `ds.add(40);` `console.log(ds.search(30));` `ds.remove(20);` `ds.add(50);` `console.log(ds.search(50));` `console.log(ds.getRandom());`

Output

```2
3
30```

Time Complexity: O(1) for all operations.
Space Complexity: O(n) for storing the elements in the data structure.