960 · Data Stream II
Algorithms
Medium 의 첫 번째 고유 번호
설명
DataStream이라는 데이터 구조를 구현해야 합니다. 구현해야 하는 두 가지 방법이 있습니다.
void add(number) // 새 숫자를 추가합니다.
int firstUnique() // 첫 번째 고유 숫자를 반환합니다.
firstUnique를 호출할 때 스트림에 하나 이상의 고유 번호가 있어야 한다고 가정할 수 있습니다.
예
예 1:
입력:
add(1)
add(2)
firstUnique()
add(1)
firstUnique()
출력:
[1,2]
예 2:
입력:
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()
출력:
[1,2,3,4,5,6]
태그
관련 문제
209 쉬운
문자열의 첫 번째 고유 문자
646
첫 위치 고유 캐릭터
쉬움
685 데이터 스트림 매체
의 첫 번째 고유 번호
해결 방법 1:
내 접근 방식은 이중 연결 목록을 기반으로 하며 두 개의 맵을 유지하면서 하나는 <num, freq>이고 다른 하나는 <num, Node *>입니다. 이중 연결 목록에는 dummyHead와 dummyTail이 있습니다. 매번 헤드 위치에 삽입되므로 dummyTail의 이전 요소 값만 반환하면 됩니다. 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;
};