[LeetCode] 23. Merge k Sorted Lists

You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.

Merge all the linked-lists into one sorted linked-list and return it.

Example 1:

Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
  1->4->5,
  1->3->4,
  2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

Example 2:

Input: lists = []
Output: []

Example 3:

Input: lists = [[]]
Output: []

Constraints:

  • k == lists.length
  • 0 <= k <= 104
  • 0 <= lists[i].length <= 500
  • -104 <= lists[i][j] <= 104
  • lists[i] is sorted in ascending order.
  • The sum of lists[i].length will not exceed 104.

合并 K 个升序链表。

给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

这道题有两种做法,时间空间复杂度一样,一个是用priority queue 解决,一个是用 merge sort 的思路解决。

首先是用 priority queue 的思路。因为JS实现 PQ 太过麻烦,所以 JS 实现我给出次优解,思路是 merge sort。

时间O(nlogk) - k 是链表的数量,最多有 k 个 node 在 pq 中,每次放一个新的 node 进去就要排序一次;所有的 node 都会被 pq 筛一遍,所以再乘以 n

空间O(n)

JavaScript实现

 1 /**
 2  * @param {ListNode[]} lists
 3  * @return {ListNode}
 4  */
 5 var mergeKLists = function (lists) {
 6     return divide(lists, 0, lists.length - 1);
 7 };
 8 
 9 var divide = function (lists, start, end) {
10     if (start === end) {
11         return lists[start];
12     } else if (start < end) {
13         const mid = parseInt(start + (end - start) / 2);
14         const left = divide(lists, start, mid);
15         const right = divide(lists, mid + 1, end);
16         return merge(left, right);
17     } else {
18         return null;
19     }
20 }
21 
22 var merge = function (left, right) {
23     if (!left) {
24         return right;
25     } else if (!right) {
26         return left;
27     } else if (left.val < right.val) {
28         left.next = merge(left.next, right);
29         return left;
30     } else {
31         right.next = merge(left, right.next);
32         return right;
33     }
34 }

 

Java实现 - priority queue

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode() {}
 7  *     ListNode(int val) { this.val = val; }
 8  *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 9  * }
10  */
11 class Solution {
12     public ListNode mergeKLists(ListNode[] lists) {
13         // corner case
14         if (lists == null || lists.length == 0) {
15             return null;
16         }
17 
18         // normal case
19         PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, (a, b) -> a.val - b.val);
20         ListNode dummy = new ListNode(0);
21         ListNode cur = dummy;
22         for (ListNode list : lists) {
23             // 注意sublist有可能是空的
24             if (list != null) {
25                 queue.add(list);
26             }
27         }
28 
29         while (!queue.isEmpty()) {
30             cur.next = queue.poll();
31             cur = cur.next;
32             if (cur.next != null) {
33                 queue.add(cur.next);
34             }
35         }
36         return dummy.next;
37     }
38 }

 

如下是Java实现的 merge sort 的思路。

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode() {}
 7  *     ListNode(int val) { this.val = val; }
 8  *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 9  * }
10  */
11 class Solution {
12     public ListNode mergeKLists(ListNode[] lists) {
13         // corner case
14         if (lists == null || lists.length == 0) {
15             return null;
16         }
17         return sort(lists, 0, lists.length - 1);
18     }
19     
20     private ListNode sort(ListNode[] lists, int lo, int hi) {
21         if (lo >= hi) {
22             return lists[lo];
23         }
24         int mid = lo + (hi - lo) / 2;
25         ListNode l1 = sort(lists, lo, mid);
26         ListNode l2 = sort(lists, mid + 1, hi);
27         return merge(l1, l2);
28     }
29     
30     private ListNode merge(ListNode l1, ListNode l2) {
31         ListNode dummy = new ListNode(0);
32         ListNode cur = dummy;
33         while (l1 != null && l2 != null) {
34             if (l1.val < l2.val) {
35                 cur.next = l1;
36                 l1 = l1.next;
37             } else {
38                 cur.next = l2;
39                 l2 = l2.next;
40             }
41             cur = cur.next;
42         }
43         if (l1 == null) {
44             cur.next = l2;
45         }
46         if (l2 == null) {
47             cur.next = l1;
48         }
49         return dummy.next;
50     }
51 }

 

相关题目

21. Merge Two Sorted Lists

23. Merge k Sorted Lists

148. Sort List

LeetCode 题目总结

posted @ 2020-01-29 00:55  CNoodle  阅读(490)  评论(0编辑  收藏  举报