Skip to content
Related Articles

Related Articles

Improve Article

Design a structure which supports insertion and first non-repeating element in O(1) time

  • Difficulty Level : Expert
  • Last Updated : 18 Dec, 2020

Design a Data structure which supports insertion and first non-repeating element in O(1) time. Operations that are supported by the data structure: 

  • Insertion: Insert a element into the data structure.
  • First non-repeating Element: First non-repeating element into the array.

Note: If there is no non-repeating element in the array then print -1. 

Consider the following custom Data structure:  

Insert(4): [4] 
Insert(1): [4, 1] 
Insert(4): [4, 1, 4]
First_Non_Repeating Element:

The idea is to use Doubly Linked List and a Hash-map to maintain the frequency of the elements of the array. Below is the use-cases of the Hash-map and Doubly-Linked List in this Data-structure: 



  • Doubly Linked-List: to keep track of the non-repeating elements in the array.
  • Hash-map: To keep track of the occurrence of the elements and the address of non-repeating elements in the Doubly Linked-List

Below is the illustration of the operations:  

  • Insertion: Insert an element into the array and check the frequency of the element into the map. If it is previously occurred then remove the element from the Doubly Linked List with the help of the addresses stored in the hash-map. Finally, increase the occurrence of the element into the hash-map.
  • First Non-repeating element: First Non-repeating element of the array will be the first element of the Doubly Linked List.

Advantages of this Data-structure:  

  • Insertion and First Non-repeating element in O(1) time.

Disadvantages of this Data-structure:  

  • Cannot Keep track of the order of the elements.
  • Custom Data-structures will need custom Hasp-map to store the elements into the map.
  • Memory Inefficient

Below is the implementation of the above approach: 

C++




// C++ implementation of a structure
// which supports insertion, deletion
// and first non-repeating element
// in constant time
 
#include <bits/stdc++.h>
 
using namespace std;
 
// Node for doubly
// linked list
struct node {
     
    // Next pointer
    struct node* next;
     
    // Previous pointer
    struct node* prev;
     
    // Value of node
    int data;
};
 
// Head and tail pointer
// for doubly linked list
struct node *head = NULL, *tail = NULL;
 
// Occurences map container
// to count for occurence
// of the element
map<int, int> occurrences;
 
// Address map container
// to store nodes of the
// list which are unique
map<int, node*> address;
 
// Function to insert the element
// into the given data-structure
void insert(int value)
{
    // Increasing count of
    // value to be inserted
    occurrences[value]++;
 
    // If count of element is
    // exactly 1 and is yet
    // not inserted in the list,
    // we insert value in list
    if (occurrences[value] == 1 &&
        address.find(value) == address.end()) {
        struct node* temp =
            (struct node*)malloc(sizeof(struct node));
        temp->next = NULL;
        temp->prev = NULL;
        temp->data = value;
         
        // Storing node mapped
        // to its value in
        // address map container
        address[value] = temp;
         
        // Inserting first element
        if (head == NULL)
        {
            head = temp;
            tail = temp;
        }
        else
        {
            // Appending
            // element at last
            tail->next = temp;
            temp->prev = tail;
            tail = temp;
        }
    }
 
    // if occurrence of particular
    // value becomes >1 and,
    // it is present in address
    // container(which means
    // it is not yet deleted)
    else if (occurrences[value] > 1 &&
        address.find(value) != address.end()) {
              
        // Taking node to be deleted
        struct node* temp = address[value];
         
        // Erasing its value from
        // map to keep track that
        // this element is deleted
        address.erase(value);
 
        // Deleting node in
        // doubly linked list
        if (temp == head) {
            temp = head;
            head = head->next;
            free(temp);
        }
        else if (temp == tail) {
            temp = tail;
            tail->prev->next = NULL;
            free(temp);
        }
        else {
            temp->next->prev = temp->prev;
            temp->prev->next = temp->next;
            free(temp);
        }
    }
}
 
// Function to find the first
// unique element from list
void findUniqueNumber()
{
    // No element in list
    if (head == NULL)
        cout << "-1\n";
         
    // Head node contains
    // unique number
    else
        cout << head->data << "\n";
}
 
 
// Driver Code
int main()
{
    // Inserting element in list
    insert(4);
    insert(1);
    insert(4);
 
    // Finding the first
    // unique number
    findUniqueNumber();
    cout << "\n";
    return 0;
}

Python3




# Python3 implementation of a structure
# which supports insertion, deletion
# and first non-repeating element
# in constant time
  
# Node for doubly
# linked list
class node:
     
    def __init__(self):
         
        # Next pointer
        self.next = None
         
        # Previous pointer
        self.prev = None
         
        # Value of node
        self.data = 0
     
# Head and tail pointer
# for doubly linked list
head = None
tail = None
  
# Occurences map container
# to count for occurence
# of the element
occurrences = dict()
  
# Address map container
# to store nodes of the
# list which are unique
address = dict()
  
# Function to insert the element
# into the given data-structure
def insert(value):
     
    global head, tail
     
    # Increasing count of
    # value to be inserted
    if value not in occurrences:
        occurrences[value] = 0
         
    occurrences[value] += 1
     
    # If count of element is
    # exactly 1 and is yet
    # not inserted in the list,
    # we insert value in list
    if (value in occurrences and
     occurrences[value] == 1 and
     value not in address):
        temp = node()
        temp.next = None
        temp.prev = None
        temp.data = value
          
        # Storing node mapped
        # to its value in
        # address map container
        address[value] = temp
          
        # Inserting first element
        if (head == None):
            head = temp
            tail = temp
        else:
             
            # Appending
            # element at last
            tail.next = temp
            temp.prev = tail
            tail = temp
 
    # If occurrence of particular
    # value becomes >1 and,
    # it is present in address
    # container(which means
    # it is not yet deleted)
    elif (value in occurrences and
        occurrences[value] > 1 and
        value in address):
               
        # Taking node to be deleted
        temp = address[value]
          
        # Erasing its value from
        # map to keep track that
        # this element is deleted
        address.pop(value)
  
        # Deleting node in
        # doubly linked list
        if (temp == head):
            temp = head
            head = head.next
            del(temp)
         
        elif (temp == tail):
            temp = tail
            tail.prev.next = None
            del(temp)
         
        else:  
            temp.next.prev = temp.prev
            temp.prev.next = temp.next
            del(temp)
             
# Function to find the first
# unique element from list
def findUniqueNumber():
     
    global head
     
    # No element in list
    if (head == None):
        print(-1)
          
    # Head node contains
    # unique number
    else:
        print(head.data)
         
# Driver Code
if __name__=='__main__':
     
    # Inserting element in list
    insert(4)
    insert(1)
    insert(4)
  
    # Finding the first
    # unique number
    findUniqueNumber()
     
# This code is contributed by rutvik_56
Output: 
1

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :