1. 程式人生 > >23. 合並K個排序鏈表

23. 合並K個排序鏈表

null htm pan || 有序鏈表 表頭 pub 相關 復雜度

知乎ID: 碼蹄疾
碼蹄疾,畢業於哈爾濱工業大學。
小米廣告第三代廣告引擎的設計者、開發者;
負責小米應用商店、日歷、開屏廣告業務線研發;
主導小米廣告引擎多個模塊重構;
關註推薦、搜索、廣告領域相關知識;

題目

合並 k 個排序鏈表,返回合並後的排序鏈表。請分析和描述算法的復雜度。
示例:
輸入:
[
1->4->5,
1->3->4,
2->6
]
輸出: 1->1->2->3->4->4->5->6

分析

前面已經做過兩個有序鏈表的合並,只要采用二分,分而治之,兩兩合並即可。時間復雜度方面,合並兩個鏈表的長度的時間復雜度是o(min(m, n)),其中m,n分別是鏈表的長度。二合並的長度是o(logk)的時間復雜度。所以整體的時間復雜度為o(klogn)

Code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        
if (l2 == null) { return l1; } ListNode merged = null; ListNode head = null; while (l1 != null && l2 != null) { if (head == null) { if (l1.val < l2.val) { merged = l1; l1 = l1.next; }
else { merged = l2; l2 = l2.next; } head = merged; continue; } if (l1.val < l2.val) { merged.next = l1; l1 = l1.next; } else { merged.next = l2; l2 = l2.next; } merged = merged.next; } while (l1 != null) { merged.next = l1; l1 = l1.next; merged = merged.next; } while (l2 != null) { merged.next = l2; l2 = l2.next; merged = merged.next; } return head; } public ListNode mergeHelper(ListNode[] lists, int low, int high) { if (low < high) { int mid = (low + high) / 2; ListNode leftList = mergeHelper(lists, low, mid); ListNode rightList = mergeHelper(lists, mid + 1, high); return mergeTwoLists(leftList, rightList); } return lists[low]; } public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } return mergeHelper(lists, 0, lists.length - 1); } }

拓展

合並兩個有序鏈表,之前采用的是非遞歸的解法。感覺代碼有點長,可以采用遞歸的解法,縮短代碼量。合並的時候選最小的元素,鏈表頭指針後移動,遞歸合並即可。

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null) {
            return null;
        }

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

相關題目

21. 合並兩個有序鏈表

技術分享圖片

23. 合並K個排序鏈表