合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
1.不使用递归
基本思路:我们可以使用分治思想 来解决这个问题。当一个链表集合中需要合并并排序。我们可以假设只有2个 每次合并两个。两个合并一个。这样就可以获取到最终的结果。
第一次将list[0]与list[len-1]合并 2次list[1]与list[len-2] 经过 for循环一次后。可以等到一半的list链表结合。在依次len = len/2; 依次合并 就可以获取到下标为0的为头结点的这个链表。
//合并两个有序的链表
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if (len == 0)
return null;
while (len > 1) {
for (int i = 0; i < len / 2; i++) {
lists[i] = merageKList(lists[i],lists[len-1-i]);
}
len = (len+1)/2;
}
return lists[0];
}
//合并两个有序的链表
private ListNode merageKList(ListNode l1, ListNode l2) {
if (l1 == null)
return null;
if (l2 == null)
return null;
ListNode listNode = new ListNode(-1);
ListNode head = listNode;
while (l1 != null && l2 != null) {
if (l1.data < l2.data) {
head.next = l1;
l1 = l1.next;
} else {
head.next = l2;
l2 = l2.next;
}
head = head.next;
}
if (l1 != null){
head.next = l1;
}else{
head.next = l2;
}
return listNode.next; //note 注意返回的不是head 返回head 会带有 -1这个结点的值 只需要后边的值 牛掰思想
}
时间复杂度:整体时间复杂度为O(N*log(k)), k为链表个数,N为链表平均长度。