解题:
- 第一种方法:
从第二个链表开始,将每一个链表插入到前面基本链表中,这个更新后的链表作为基本链表。
暴力解法:对新插入的链表中的每一个元素都去基本链表中从头找自己要插入的位置
暴力解法稍稍优化后:对新插入的链表中的每一个元素都去基本链表中找自己要插入的位置,起始头从当前插入位置开始。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if lists:
head = ListNode()
head.next = lists[0]
for node in lists[1:]:
frontnode = head
basenode = frontnode.next
while (node):
while(basenode and node.val >= basenode.val):
frontnode = basenode
basenode = basenode.next
frontnode.next = node
if basenode == None:
break
while(node.next and node.next.val < basenode.val):
node = node.next
tmpnode = node.next
node.next = basenode
frontnode = node
node = tmpnode
return head.next
else:
return None
- 继续优化:
1.找第一个插入的位置可以不用顺序查找而用二分查找。
2.每次遍历完有一定的先验知识了,可以用哈希表之类的存储,对下一个链表的插入提供帮助。【空间换时间】
- 第二种方法:
基本思路:k个列表k个指针,从k个列表中pick出最小值的结点,然后该列表的头指针后移一位。循环,直到所有节点被pick。
优化:如果每次都临时比较,那么每个被pick的节点要进行k次比较,共kn个节点,复杂度就是k^2 ✖n。但实际上每轮比较只会pick出1个,剩下k-1个应该可以有序排列了,这样可以有助于下次pick。因此,选用优化队列(堆)这种数据结构来实现该功能,可将比较复杂度从k降低至logk。
import heapq
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
def __lt__(self, other):
return self.val < other.val
ListNode.__lt__ = __lt__
head = tail = ListNode()
q = []
for l in lists:
if l:
heapq.heappush(q,l)
while q:
node = heapq.heappop(q)
tail.next = node
tail = tail.next
if node.next:
heapq.heappush(q, node.next)
return head.next
- 第三种方法:
基本思路:
归并排序(分而治之)对于第一种方法的逐一合并,可以采用分而治之。链表两两配对合并。复杂度为nklogk
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if lists:
return self.mergeTwoLists(lists[0:int(len(lists)/2)], lists[int(len(lists)/2):])
else:
return None
def mergeTwoLists(self, A: List[ListNode], B: List[ListNode]) -> ListNode:
if len(A) > 1:
A = self.mergeTwoLists(A[0:int(len(A)/2)], A[int(len(A))/2:])
elif A == []:
A = None
else:
A = A[0]
if len(B) > 1:
B = self.mergeTwoLists(B[0:int(len(B)/2)], B[int(len(B)/2):])
elif B == []:
B = None
else:
B = B[0]
head = ListNode()
frontnode = head
head.next, basenode = A, A
node = B
while node:
while(basenode and node.val >= basenode.val):
frontnode = basenode
basenode = basenode.next
frontnode.next = node
if basenode == None:
break
while(node.next and node.next.val < basenode.val):
node = node.next
tmpnode = node.next
node.next = basenode
frontnode = node
node = tmpnode
return head.next