1. 程式人生 > 實用技巧 >LeetCode23.合併K個有序連結串列

LeetCode23.合併K個有序連結串列

題目描述:

給你一個連結串列陣列,每個連結串列都已經按升序排列。

請你將所有連結串列合併到一個升序連結串列中,返回合併後的連結串列。

解法一:利用堆。

將K個連結串列的頭節點放入堆中,然後依次取出,如果節點後面還有節點,就將節點繼續放入堆中。

時間複雜度:O(kn*logk),n是連結串列中的元素個數,k是連結串列個數

空間複雜度:這裡用了優先佇列,優先佇列中的元素不超過k個,故漸進空間複雜度為O(k)。

import java.util.Comparator;
import java.util.PriorityQueue;

public class Solution {
    
public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length < 0){ return null; } //定義優先佇列,以及排序規則。 PriorityQueue<ListNode> queue = new PriorityQueue<>(new Comparator<ListNode>() { @Override public
int compare(ListNode o1, ListNode o2) { return (o1.val - o2.val); } }); ListNode dummyNode = new ListNode(-1); ListNode curNode = dummyNode; //把k個連結串列的第一個節點放入堆中 for (int i = 0; i < lists.length; i++){ ListNode head = lists[i];
if(head != null){ queue.add(head); } } //不斷的從堆中取出節點,如果節點還有下一個節點,就把下一個節點也放入堆中。 while(!queue.isEmpty()){ ListNode node = queue.poll(); curNode.next = node; curNode = curNode.next; if(node.next != null){ queue.add(node.next); } } curNode.next = null; return dummyNode.next; } }

解法二:可以將K個連結串列逐漸縮小成規模為1的K個連結串列進行比較,最後在合併成原始規模的連結串列

時間複雜度:O(kn*logk)

空間複雜度:遞迴會使用到O(logk)空間代價的棧空間。

public class Solution2 {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0){
            return null;
        }
        return helper(lists,0,lists.length-1);
    }

    private ListNode helper(ListNode[] lists, int left, int right) {
        if(left == right){
            return lists[left];
        }
        int mid = left + (right - left) / 2;
        ListNode l1 = helper(lists,left,mid);
        ListNode l2 = helper(lists,mid + 1,right);
        return mergeTwoLists(l1,l2);
    }

    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null){
            return l2;
        }
        if(l2 == null){
            return l1;
        }
        if(l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }else {
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}