【Lintcode】960. First Unique Number in Data Stream II
阿新 • • 發佈:2020-12-27
技術標籤:# 棧、佇列、串及其他資料結構連結串列資料結構java雜湊表
題目地址:
https://www.lintcode.com/problem/first-unique-number-in-data-stream-ii/description
要求實現一個數據結構,可以實現下面操作:
1、新增一個數字;
2、求按新增順序來看,第一個只出現過一次的數字。
可以用雜湊表 + 連結串列來做。雜湊表key存數字,value存連結串列節點。我們開兩個變數,一個dummy節點,還有一個tail節點,tail節點存連結串列的最後一個節點。該連結串列就存所有按新增順序的且只出現過一次的數字。具體是這樣做的。當新增一個數字的時候,先看雜湊表的key裡有沒有,如果有了,那麼這個數字再也不可能是唯一數字了,就將其從連結串列中刪除,並將這個數字對應的value存為null,表示該數字永不考慮(如果新增的數字在雜湊表裡有key,但value是null,則直接返回就行);如果雜湊表裡沒有,則說明該數字是唯一數字,新增到連結串列結尾。返回唯一數字,其實就是返回dummy.next的value。程式碼如下:
import java.util.HashMap;
import java.util.Map;
public class DataStream {
class ListNode {
int val;
ListNode prev, next;
public ListNode(int val) {
this.val = val;
}
}
private ListNode dummy, tail;
private Map<Integer, ListNode> map;
public DataStream() {
// do intialization if necessary
map = new HashMap<>();
dummy = tail = new ListNode(0);
}
/**
* @param num: next number in stream
* @return: nothing
*/
public void add(int num) {
// write your code here
if (map.containsKey(num)) {
// 如果雜湊表裡有num這個key,但value是null,
// 意味著這個num永遠不會是唯一數字,直接return
if (map.get(num) == null) {
return;
}
// 否則說明num這個數字之前只出現過一次,這是第二次新增,則將第一次新增的那個節點刪掉
ListNode node = map.get(num);
// 其value置為null
map.put(num, null);
node.prev.next = node.next;
// 刪除的時候要考慮node自己是不是tail,如果是,則要更新tail
if (node.next != null) {
node.next.prev = node.prev;
} else {
tail = node.prev;
}
} else {
// 如果雜湊表裡沒有num這個key,說明num是第一次見,則加在連結串列結尾
tail.next = new ListNode(num);
tail.next.prev = tail;
tail = tail.next;
map.put(num, tail);
}
}
/**
* @return: the first unique number in stream
*/
public int firstUnique() {
// write your code here
return dummy.next.val;
}
}
所有操作時間複雜度 O ( 1 ) O(1) O(1),空間複雜度取決於具體輸入。