合并K个排序链表

154 阅读2分钟

合并K个排序链表


今天是一道难度为hard的题目,来自leetcode,但是通过率并不低,Acceptance为51.7%。

题目如下


合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/me… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

回复0000查看更多题目

解题思路


思路一

初看该题似乎并不难,因为链表都是有序的,假设有K个链表,取K 个指针分别指向 K条链表,并从逐个链表头取数据并比较,取最小的插入新的链表,然后指针后移;直到每个链表都到结尾就能得到最后的结果。考虑一下这种算法的时间复杂度。

假设所有链表的元素总数和是N,因为有K个链表,每次都是比较K词,所以总的时间复杂度是O(KN)

代码如下


Java版

class Solution {
    public ListNode mergeKLists(ListNode[] lists) { 
        int k = lists.length;
        ListNode dummyHead = new ListNode(0);
        ListNode tail = dummyHead;
        while (true) {
            ListNode minNode = null;
            int minPointer = -1;
            for (int i = 0; i < k; i++) {
                if (lists[i] == null) {
                    continue;
                }
                if (minNode == null || lists[i].val < minNode.val) {
                    minNode = lists[i];
                    minPointer = i;
                }
            }
            if (minPointer == -1) {
                break;
            }
            tail.next = minNode;
            tail = tail.next;
            lists[minPointer] = lists[minPointer].next;
        }
        return dummyHead.next;
    }
}
思路二

考虑上面的思路有没有优化空间,因为每次取K个值都需要重新比较,仔细思考这里只有1个值是新的,另外的K-1个值已经比较过是有序了,那么只需要比较这个新的值就可以了。如何实现呢?

可以使用小根堆进行优化,用一个小跟堆维护比较比较过的K-1个值,这样每次比较 K个指针求 min只需要 O(logK)次比较, 时间复杂度:O(NlogK)

Java版

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        Queue<ListNode> pq = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);
        for (ListNode node: lists) {
            if (node != null) {
                pq.offer(node);
            }
        }

        ListNode dummyHead = new ListNode(0);
        ListNode tail = dummyHead;
        while (!pq.isEmpty()) {
            ListNode minNode = pq.poll();
            tail.next = minNode;
            tail = minNode;
            if (minNode.next != null) {
                pq.offer(minNode.next);
            }
        }

        return dummyHead.next;
    }
}

关注我

回复0000查看更多题目

image