题目描述
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
思路
首先最先想到的依旧是暴力法,遍历每一个点,放入一个数组中,然后对数组进行排序。这样的时间复杂度是O(NLogN)
其次就想到了 合并两个排序数组的这道题,那么就可以想到我们两个两个去合并,这样的时间复杂度是O(KN),k是链表的个数
最后可以想一下怎么优化,因为两两比较有很多重复的步骤,可以想到分治,时间复杂度可以到O(NLogK)
代码
py版
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
amount = len(lists)
if amount == 0:
return None
interval = 1
while interval < amount:
for i in range(0, amount - interval, interval * 2):
lists[i] = self.merge2Lists(lists[i], lists[i + interval])
interval *= 2
return lists[0] if amount > 0 else lists
def merge2Lists(self, l1, l2):
head = point = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
point.next = l1
l1 = l1.next
elif l1.val >= l2.val:
point.next = l2
l2 = l2.next
point = point.next
if not l1:
point.next = l2
else:
point.next = l1
return head.next
js版
var mergeKLists = function(lists) {
if(lists.length == 0)
return null;
for(let i = 1; i < lists.length; i*=2){
for(let j = 0; j < lists.length - i; j += (2 * i)){
lists[j] = mergeTwoList(lists[j], lists[j + i]);
}
}
return lists[0];
};
var mergeTwoList = function(l1, l2){
let newList = pointer = new ListNode(0);
while(l1 && l2){
if(l1.val > l2.val){
pointer.next = l2
l2 = l2.next;
}else{
pointer.next = l1;
l1 = l1.next;
}
pointer = pointer.next;
}
if(!l1)
pointer.next = l2;
else
pointer.next = l1;
return newList.next;
}