接續前一天的策略,隨手從 Leetcode Linked List 題組中挑了一個 Hard 的題目。

之前做過 Merge two Sorted Lists,這題算是那一題的變形、Follow-up。

https://leetcode.com/problems/merge-k-sorted-lists

Solution

看完題目後,偷瞄了一下 Topics 發現跟 heap、priority queue 有關。當下還沒仔細思考複雜度,但腦中瞬間有了一個解法。

建立一個 priority_queue,遍歷所有 Linked Lists 中的 elements,並且加到 priority queue 裡面。

接著再依序取 priority queue 的 top(最小值)並且 pop,直到 queue 變成空的。

題目的限制是:

  • Linked List 的數量: k (0 ≤ k ≤ 10⁴)
  • Linked List 中元素個數: n (0 ≤ n ≤ 500)

最多有 10⁶ 個元素,時間複雜度會是 O(nk*ln(nk)),大約需要 10⁶ * ln10⁶ 次計算。

空間複雜度是 O(nk),因為需要一個儲存所有元素的 priority queue。

不過,使用 priority queue 就沒辦法用到題目給的 sorted 的好處。AC 後看其他人的 solution 是 divide and conquer,就能利用到這個好處了。

Note

Priority Queue

是一個 heap 的結構,C++ STL (standard template library) 也有這個資料結構。

在 C++ STL 實作中,priority queue 的 declaration 是:

template<  
    class T,  
    class Container = std::vector<T>,  
    class Compare = std::less<typename Container::value\_type>  
\> class priority\_queue;

預設會由大排到小,如果要由小到大,需要指定 Compare 為 std::greater<int>
Compare return true,會越晚從 priority queue 被 pop 出來。

值得注意的是,STL container 有幾種類別:

  • sequence containers
    如 array、vector、list、deque
  • associative containers
    如 set、map
  • unordered associative containers
    如 unordered_set、unordered_map

但,priority queue 其實並不屬於以上的任何一個類別。priority queue 是一個 container adaptor,用來提供不同的 interface 給 sequence container

這也是為什麼在 template 的 declaration 中,第二個 template parameter 會是 container。

Leetcode address sanitizer

第一次寫完 submit 的時候發現會一直出現以下的錯誤:

AddressSanitizer: attempting free on address which was not malloc()-ed

後來檢查了一下,在程式碼中有一個 ListNode *head;,沒有被初始化為一個 ListNode 的 object 或者是 nullptr

Conclusion

submit 出現的各種 error(如 AddressSanitizer)有空可以再更仔細的追究發生的原因。