960 · First Unique Number in Data Stream II
Algorithms
Medium
Description
We need to implement a data structure named DataStream. There are two methods required to be implemented:
void add(number) // add a new number
int firstUnique() // return first unique number
You can assume that there must be at least one unique number in the stream when calling the firstUnique.
Example
Example 1:
Input:
add(1)
add(2)
firstUnique()
add(1)
firstUnique()
Output:
[1,2]
Example 2:
Input:
add(1)
add(2)
add(3)
add(4)
add(5)
firstUnique()
add(1)
firstUnique()
add(2)
firstUnique()
add(3)
firstUnique()
add(4)
firstUnique()
add(5)
add(6)
firstUnique()
Output:
[1,2,3,4,5,6]
Tags
Related Problems
209
First Unique Character in a String
Easy
646
First Position Unique Character
Easy
685
First Unique Number in Data Stream
Medium
解法1:
我的做法是基于doubly linked list,同时维护两个map,一个是<num, freq>,一个是<num, Node *>。注意doubley linked list有一个dummyHead, 一个dummyTail。每次都插到head的位置,这样只需要返回dummyTail前面一个元素的值就可以了。注意每次add num的时候,如果发现freq[num]>1了,需要把num对应的Node 节点删除。每次操作应该都是O(1)。
struct Node {
int val;
Node *prev, *next;
Node(int v) : val(v), prev(NULL), next(NULL) {}
};
class DataStream {
public:
DataStream(){
dummyHead = new Node(0);
dummyTail = new Node(0);
dummyHead->next = dummyTail;
dummyTail->prev = dummyHead;
}
/**
* @param num: next number in stream
* @return: nothing
*/
void add(int num) {
freq[num]++;
//delete repeat node from doubly linked list
if (freq[num] > 1 && mp.find(num) != mp.end()) {
Node *deleteNode = mp[num];
deleteNode->prev->next = deleteNode->next;
deleteNode->next->prev = deleteNode->prev;
delete(deleteNode);
deleteNode = nullptr;
mp.erase(num);
}
//always add to head
if (freq[num] == 1) {
Node *node = new Node(num);
node->next = dummyHead->next;
if (dummyHead->next) dummyHead->next->prev = node;
node->prev = dummyHead;
dummyHead->next = node;
mp[num] = node;
}
}
/**
* @return: the first unique number in stream
*/
int firstUnique() {
//if (dummyHead->next == dummyTail) return -1; //但题目保证有至少一个unique,所以这行不需要
return dummyTail->prev->val;
}
private:
unordered_map<int, Node *> mp;
unordered_map<int, int> freq; //<int, freq>
Node *dummyHead, *dummyTail;
};
解法2:用queue和unordered_map。
注意: 虽然firstUnique()里面有while(),其均摊时间复杂度仍然是O(1)。
class DataStream {
public:
DataStream(){
}
/**
* @param num: next number in stream
* @return: nothing
*/
void add(int num) {
q.push(num);
freq[num]++;
}
/**
* @return: the first unique number in stream
*/
int firstUnique() {
while(!q.empty() && freq[q.front()] > 1) {
q.pop();
}
if (q.empty()) return -1;
return q.front();
}
private:
queue<int> q;
unordered_map<int, int> freq; //<int, freq>
};