Итак, я недавно внедрил «Первый уникальный номер» в Leetcode. Вопрос, для справки, выглядит примерно так:
У вас есть очередь целых чисел, вам нужно получить первое уникальное целое число в очереди.
Реализация класса FirstUnique:
- FirstUnique (int [] nums) Инициализирует объект с номерами в очереди.
- int showFirstUnique () возвращает значение первого уникального целого числа очереди и возвращает -1, если такого целого числа нет.
- void add (int value) вставить значение в очередь.
Моя реализация C ++ с использованием STL использует unordered_map и список. Карта хранит элементы очереди в виде ключей и сохраняет итератор, указывающий на элемент в списке, и логическое значение, указывающее на удаление значения из списка, когда оно перестает быть уникальным. Добавление и удаление элементов в списке являются операциями с постоянным временем. Тем не менее, мое решение намного медленнее по сравнению с другим решением, которое использует очередь и выполняет итерацию по очереди (в основном это O (n) по сравнению с моим O (1)).
Здесь явно хуже решение:
class FirstUnique {
private:
queue<int> q;
unordered_map<int, int> count;
public:
FirstUnique(vector<int>& nums) {
for(int num: nums){
count[num]++;
q.push(num);
}
}
int showFirstUnique() {
while(!q.empty() && count[q.front()] > 1){
q.pop();
}
if(q.empty()){
return -1;
}
else{
return q.front();
}
}
void add(int value) {
if(++count[value] == 1){
q.push(value);
}
}
};
Это мое решение:
class FirstUnique {
public:
unordered_map<int, pair<list<int>::iterator, bool>> hashmap;
list<int> l;
FirstUnique(vector<int>& nums) {
for(auto it=nums.begin(); it!=nums.end(); it++)
add(*it);
}
int showFirstUnique() {
if (l.empty())
return -1;
return l.back();
}
void add(int value) {
unordered_map<int, pair<list<int>::iterator, bool>>::iterator it = hashmap.find(value);
if(it == hashmap.end())
{
l.push_front(value);
hashmap[value] = make_pair(l.begin(), false) ;
}
else
{
if((it->second).second == false)
{
l.erase((it->second).first);
(it->second).second = true;
}
}
}
};
Что я не понимаю, так это то, что, несмотря на мое быстрое решение, время выполнения намного медленнее. Тот, чья очередь составлял 328 мс, а мой - 532 мс по Leetcode. Я могу понять, что мое решение требует большой памяти, но не могу понять, почему оно медленнее.