iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
自我挑戰組

用java解Leetcode系列 第 23

用java解Leetcode Day23

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251007/20169501QetPaLLvwY.pnghttps://ithelp.ithome.com.tw/upload/images/20251007/20169501ULkD5F0GdR.png

  1. Merge k Sorted Lists

這是「合併k個已排序鏈結串列」問題。
這個問題要求將一個包含k個已排序鏈結串列(Linked Lists)的陣列lists合併成一個單一的、完整排序的鏈結串列,並回傳這個新的鏈結串列的頭部(Head)。
這題需要找到所有節點中的最小值,將其作為新串列的第一個節點,然後從該串列中移除該節點。重複這個過程,直到所有的串列都為空。

由於所有鏈結串列都已排序,需要一種高效的方式來同時追蹤k個串列的目前節點,並在每一輪中快速找到k個節點中的最小值,而這個方法就是優先佇列(Priority Queue),在java中即為java.util.PriorityQueue。這個方法能確保我們在k個串列頭部節點中,已O(log k)的時間複雜度找到最小值。
首先,要定義鏈結串列節點(ListNode),但這次LeetCode已經提供,所以略過。
接著,建立一個最小堆(Min-Heap)結構的優先佇列,用來儲存k個鏈結串列的頭部節點。佇列中的節點會根據它們的 val(值)進行排序。
再來,遍歷輸入lists陣列,將所有非空的鏈結串列的頭部節點加入優先佇列。
上述完成後,建立一個虛擬頭部(Dummy Head)節點dummy,並使用一個指標tail來追蹤新串列的尾部,以便於附加新節點。
只要優先佇列不為空,就重複以下動作:

1.取出最小值:從佇列中取出(poll)值最小的節點smallest。

2.附加到結果串列:將smallest節點附加到結果串列的尾部(即tail.next = smallest),並移動tail指標到新的尾部。

3.加入下一個節點:檢查smallest節點是否有下一個節點(smallest.next != null)。如果有,將這個下一個節點加入優先佇列。

最終回傳dummy.next,它就是合併後鏈結串列的頭部。

複雜度分析

時間複雜度: O(N log k)

1.N 是所有鏈結串列中的節點總數(即 ∑lists[i].length)。

2.佇列中最多會有 k 個元素。

3.每個節點都會被加入和取出佇列一次。

4.每次加入或取出操作的時間複雜度是 O(logk)。

5.因此總時間複雜度為 N×O(logk)=O(Nlogk)。

空間複雜度: O(k)

1.優先佇列最多會同時儲存 k 個節點(每個串列一個頭部)。

這個 O(N log k) 的解法是最高效的,因為它平衡了「遍歷所有節點」 (O(N)) 和「在 k 個選項中找最小值」 (O(log k)) 這兩個核心操作。


上一篇
用java解Leetcode 22
系列文
用java解Leetcode23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言