https://leetcode.com/problems/delete-nodes-from-linked-list-present-in-array/description/
給一個 linked list 跟整數陣列 nums
把 nums
中有出現的數字從 linked list 中移除並回傳新的串列頭
Constraints:
nums.length
nums[i]
nums
中的元素全相異Node.val
nums
中這題不難,兩個重點會就輕輕鬆鬆
nums
中這邊再次給不熟悉資料結構的做簡單說明
先談查找,以時間複雜度作為理論依據來說,我們要在陣列中尋找到某個值的時間複雜度是 ,其中 m
為 nums.size()
我們要想刪除 linked list 中的節點,由於我們只有 head
的位置,所以我們勢必要從頭到尾遍歷 linked list 一遍,若 linked list 長度為 n
則我們每到達一個節點就要花費 的時間確認 Node.val
是否在 nums
中
這樣的時間複雜度是
所以一個相當直觀的想法是,我們可以事先確認 nums
都有哪些值
如果我們使用 unordered_set
來記錄:
插入的平均時間複雜度為 ,所以建立表的時間是
查找的平均複雜度我們也能視為 ,遍歷的時候我們每次只花 ,所以我們所以查找整條 linked list 也就花
時間複雜度這樣下來變成了
以演算法來說,回答到這就已經相當不錯,可以交卷了
不過使用 unordered_set
有個問題,那就是它的原理實際依賴 hash table ,這個的原理簡單來說就是透過設計好的 hash function 在平均來說 之下得到資料的索引
然而,在最壞的情況下,查找可能會退化回線性
由於這題我們只是需要知道 Node.val
是否在 nums
中
所以一個更好的選擇是用 bitset
時間複雜度來看兩個選擇的演算法是一樣的
然而以這題來說,我們會發現基於位運算的 bitset
時間表現上會更好一些
以下為最後的參考解答
這邊用了 linked list 的一個小技巧,就是設一個 dummy node (在 head
前新加一個沒有要用的節點,這樣我們永遠看當前節點的下一個節點就好,也就是 curr->next
)
這樣下面寫 code 會比較簡潔好寫