1. 程式人生 > 其它 >【Lintcode】960. First Unique Number in Data Stream II

【Lintcode】960. First Unique Number in Data Stream II

技術標籤:# 棧、佇列、串及其他資料結構連結串列資料結構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),空間複雜度取決於具體輸入。