23.合并K个升序链表
题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
| 输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
|
示例 2:
示例 3:
提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i]
按 升序 排列
lists[i].length
的总和不超过 10^4
题解
解法一
| /**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
//执行用时: 278 ms
//内存消耗: 40.9 MB
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists == null || lists.length == 0)return null;
ListNode cur = lists[0];
//遍历所有的链表
for(int i = 1;i < lists.length;i++){
cur = merge(cur,lists[i]);
}
return cur;
}
//两个有序链表合并
private ListNode merge(ListNode l1,ListNode l2){
if(l1==null)return l2;
if(l2==null)return l1;
if(l1.val <= l2.val){
l1.next = merge(l1.next,l2);
return l1;
}else{
l2.next = merge(l1,l2.next);
return l2;
}
}
}
|
解法二分治算法
| /**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
//
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists == null || lists.length == 0) return null;
sort(lists,0,lists.length-1);
return lists[0];
}
//参考算法第四版的归并排序
//1. 利用sort方法拆分成[1] [2] [3] [4]
//2. 归并
//和归并排序的区别
//merge的时候不需要知道开始和结束的索引
private void sort(ListNode[] lists, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(lists, lo, mid); //将左半边排序
sort(lists, mid + 1, hi); //将右半边排序
lists[lo] = merge(lists[lo],lists[mid+1]); //归并结果
lists[mid+1]=null;
}
private ListNode merge(ListNode l1,ListNode l2){
if(l1==null)return l2;
if(l2==null)return l1;
if(l1.val <= l2.val){
l1.next = merge(l1.next,l2);
return l1;
}else{
l2.next = merge(l1,l2.next);
return l2;
}
}
}
|
| //官方分治算法代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return merge(lists, 0, lists.length - 1);
}
public ListNode merge(ListNode[] lists, int l, int r) {
if (l == r) {
return lists[l];
}
if (l > r) {
return null;
}
int mid = (l + r) >> 1;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
public ListNode mergeTwoLists(ListNode a, ListNode b) {
if (a == null || b == null) {
return a != null ? a : b;
}
ListNode head = new ListNode(0);
ListNode tail = head, aPtr = a, bPtr = b;
while (aPtr != null && bPtr != null) {
if (aPtr.val < bPtr.val) {
tail.next = aPtr;
aPtr = aPtr.next;
} else {
tail.next = bPtr;
bPtr = bPtr.next;
}
tail = tail.next;
}
tail.next = (aPtr != null ? aPtr : bPtr);
return head.next;
}
}
|