在恒定时间内返回流中的第一个唯一编号

时间:2017-09-21 21:03:52

标签: algorithm

如果当前数字是终止数字(例如零),如何编写一个静态函数,该函数返回数字流中的第一个唯一数字。否则,它应该返回零。

static int firstUnique(int number);

时间复杂度应为O(1)。我应该使用什么数据结构?

1 个答案:

答案 0 :(得分:1)

使用地图和双重链接列表:

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int TERMINATOR = 0;

struct Node {
   int data;
    Node* next;
    Node* prev;
};


int firstUnique(int number){
    static unordered_map<int, Node*> numToIsUnique;
    static Node* head = nullptr; // first unique
    static Node* tail = nullptr; // last unique
    if (number != TERMINATOR){
        Node* newNode = new Node{number, nullptr, nullptr};
        if (numToIsUnique.insert(make_pair(number, newNode)).second == false) {
      // insert fails => number is not unique
      // Need to delete from LinkedList
      Node* nodeToDelete = numToIsUnique[number];

      if (nodeToDelete != nullptr){ // delete only once
          if (head == nodeToDelete && tail == nodeToDelete){
            // head == tail - one node
               head = nullptr;
               tail = nullptr;
          }
          else if (head == nodeToDelete){
            // head to delete
              head = head->next;
              head->prev = nullptr;
          }
          else if (tail == nodeToDelete){
              // tail to delete
              tail = tail->prev;
              tail->next = nullptr;
          }
          else {
              // delete node in the middle
              nodeToDelete->prev->next = nodeToDelete->next;
              nodeToDelete->next->prev = nodeToDelete->prev;
          }

          delete nodeToDelete;
          numToIsUnique[number] = nullptr;
      }
    }
    else {
        // number is new => need to append at the end of link list (last unique)
        if (head == nullptr){
          // list is empty
             head = newNode;
             tail = head; 
        }
        else if (head == tail){
          // list has one node
          tail = newNode;
          newNode->prev = head;
          head->next = tail;
        }
        else {
          // list has more than one node
            newNode->prev = tail;  
            tail->next = newNode;
            tail = newNode;
        }
    }
    return TERMINATOR;
}
else {
  // Output head
    if (head == nullptr){
        return TERMINATOR;
    }
    else {
        return head->data; 
    }

    }
}