题目:
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例:
输入: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
思路:
之前写过一道合并两个链表的题目。这次要借用这个方法。
最简单的思路就是遍历整个链表集合,逐一合并,见代码一,但是这个时间复杂度比较高
就相当于遍历逐个遍历上一种,那自然可以想到两两合并的归并算法,和快排一个思路,见代码二
复杂度:
时间复杂度:O(nlogn)
空间复杂度:O(1)
代码:
代码一:
public ListNode mergeKLists(ListNode[] lists) {
//和之前的合并两个应该有点类似,将其写成方法进行调用
//逐一对两个队列进行合并
//照这个思路应该就是两轮循环,复杂度是On2
ListNode res = null;
for(ListNode list : lists){
res = mergeTwoLists(res,list);
}
return res;
}
private ListNode mergeTwoLists(ListNode list1,ListNode list2){
ListNode node = new ListNode(0);
ListNode cur = node;
while(list1!=null && list2!=null){
if(list1.val >= list2.val){
cur.next = list2;
list2 = list2.next;
}else{
cur.next = list1;
list1 = list1.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1;
return node.next;
}
代码二:
public ListNode mergeKLists(ListNode[] lists) {
//两两合并
if(lists.length == 0) return null;
return merge(lists,0,lists.length-1);
}
private ListNode merge(ListNode[] lists,int l,int r){
if(l==r) return lists[l];
int mid = l+((r-l)>>1);
ListNode L1 = merge(lists,l,mid);
ListNode L2 = merge(lists,mid+1,r);
return mergeTwoLists(L1,L2);
}
private ListNode mergeTwoLists(ListNode list1,ListNode list2){
ListNode node = new ListNode(0);
ListNode cur = node;
while(list1!=null && list2!=null){
if(list1.val >= list2.val){
cur.next = list2;
list2 = list2.next;
}else{
cur.next = list1;
list1 = list1.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1;
return node.next;
}