📌  相关文章
📜  设计一个在 O(1) 时间内支持插入和第一个非重复元素的结构

📅  最后修改于: 2021-09-06 05:35:29             🧑  作者: Mango

设计一个支持在 O(1) 时间内插入和第一个非重复元素的数据结构。数据结构支持的操作:

  • 插入:在数据结构中插入一个元素。
  • 第一个非重复元素:数组中的第一个非重复元素。

注意:如果数组中没有非重复元素,则打印 -1。

考虑以下自定义数据结构:

这个想法是使用双向链表和哈希映射来维护数组元素的频率。以下是此数据结构中哈希映射和双向链表的用例:

  • 双向链表:跟踪数组中的非重复元素。
  • Hash-map:跟踪双向链表中元素的出现和非重复元素的地址

下图是操作示意图:

  • 插入:向数组中插入一个元素,并检查该元素进入地图的频率。如果之前发生过,则借助哈希映射中存储的地址从双向链表中删除该元素。最后,将元素的出现次数增加到哈希映射中。
  • 第一个非重复元素:数组的第一个非重复元素将是双向链表的第一个元素。

这种数据结构的优点:

  • 在 O(1) 时间内插入和第一个非重复元素。

这种数据结构的缺点:

  • 无法跟踪元素的顺序。
  • 自定义数据结构将需要自定义 Hasp-map 将元素存储到地图中。
  • 内存效率低下

下面是上述方法的实现:

C++
// C++ implementation of a structure
// which supports insertion, deletion
// and first non-repeating element
// in constant time
 
#include 
 
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 occurrences;
 
// Address map container
// to store nodes of the
// list which are unique
map 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


输出:
1

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live