设计一个支持在 O(1) 时间内插入和第一个非重复元素的数据结构。数据结构支持的操作:
- 插入:在数据结构中插入一个元素。
- 第一个非重复元素:数组中的第一个非重复元素。
注意:如果数组中没有非重复元素,则打印 -1。
考虑以下自定义数据结构:
Insert(4): [4]
Insert(1): [4, 1]
Insert(4): [4, 1, 4]
First_Non_Repeating Element: 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