1. 程式人生 > >leecode刷題(27)-- 合並k個排序鏈表

leecode刷題(27)-- 合並k個排序鏈表

總結 not 時間 klist 讀取 empty 元素 add 回合

leecode刷題(27)-- 合並k個排序鏈表

合並k個排序鏈表

合並 k 個排序鏈表,返回合並後的排序鏈表。請分析和描述算法的復雜度。

示例:

輸入:
[
  1->4->5,
  1->3->4,
  2->6
]
輸出: 1->1->2->3->4->4->5->6

思路

以前做過合並兩個有序鏈表的問題,所以剛開始想到的解法與之類似,我們可以先合並兩個有序鏈表,再用合並的新鏈表去合並第三個鏈表:

1->1->3->4->4->5
1->1->2->3->4->4->5->6

其實如果我們學習過堆相關的知識,還可以用最小堆來解決這個問題:

  1. 讀取所有鏈表值
  2. 構造一個最小堆(python中有 headp 方法,java中有 PriorityQueue 方法
  3. 根據最小堆構造一個鏈表

代碼如下

python 描述

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

from heapq import heapify, heappop

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        
        # 讀取所有節點值
        h = []
        for node in lists:
            while node:
                h.append(node.val)
                node = node.next

        if not h:
            return None
        
        # 構造一個最小堆
        heapify(h)  # 轉換為最小堆

        # 構造鏈表
        root = ListNode(heappop(h))
        curnode = root
        while h:
            nextnode = ListNode(heappop(h))
            curnode.next = nextnode
            curnode = nextnode
        return root

java 描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        // 讀取所有節點值
        List<Integer> h = new ArrayList();
        for (ListNode node: lists) {
            while (node != null) {
                h.add(node.val);
                node = node.next;
            }
        }

        // 構造一個最小堆
        if (!h.isEmpty())   return null;
        PriorityQueue<ListNode> priorityQueue = new PriorityQueue();
        // 將元素添加進最小堆中
        for (Integer h1: h) {
            priorityQueue.offer(h1);
        }

        //構造鏈表
        ListNode root = priorityQueue.poll();
        ListNode curNode = root;
        while (!priorityQueue.isEmpty()) {
            ListNode nextNode = priorityQueue.poll();
            curNode.next = nextNode;
            curNode = nextNode;
        }
        return root;
    }
}

總結

上述 python 的代碼能通過提交,但是 java 代碼部分我快被類型轉換弄暈了,代碼不能通過運行,這裏只是給出一種思路,日後有時間自己會再完善的,寫下來也是當作自己學習記錄的一部分,希望看到文章的小夥伴能幫忙指出本人的不足。

leecode刷題(27)-- 合並k個排序鏈表