yedaoxiaodi 2020-01-04
合并?k?个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
#输入: [ ? 1->4->5, ? 1->3->4, ? 2->6 ] #输出: 1->1->2->3->4->4->5->6
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
在k个链表中找到一个比较节点,然后把k个链表分成两部分,一部分都比比较节点小,一部分都比比较节点大,然后递归。
但是时间太慢了,原因一个是,找到的比较节点越靠近中位数越好,但是不好操作,第二个就是分成两部分的时候要查找,只能顺序查找。(变成数组也许会好一点,二分)
import random class Solution: def mergeKLists(self, lists)-> ListNode: lists = [list for list in lists if list is not None] if len(lists)==0: return None num = len(lists) i = random.randint(0,num-1) com_node = lists[i] com_val = lists[i].val lists[i] = lists[i].next lists_1 = [] for j in range(num): if i!=j: head = lists[j] tail = None while lists[j].val<=com_val: tail = lists[j] lists[j] = lists[j].next if lists[j] is None: break if tail is not None: tail.next = None lists_1.append(head) list_1 = self.mergeKLists(lists_1) list_2 = self.mergeKLists(lists) if list_1 is not None: head = list_1 while True: if list_1.next is not None: list_1 = list_1.next else: list_1.next = com_node break else: head = com_node com_node.next = list_2 return head
每次合并两个链表,合并一次之后剩余k/2,再合并一次剩余k/4。时间复杂度(NlogK)
class Solution(object): def mergeKLists(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ amount = len(lists) 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 else: point.next = l2 l2 = l1 l1 = point.next.next point = point.next if not l1: point.next=l2 else: point.next=l1 return head.next
from queue import PriorityQueue class ListNode: def __init__(self, x): self.val = x self.next = None def __lt__(self, other): return self.val<other.val class Solution(object): def mergeKLists(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ head = point = ListNode(0) q = PriorityQueue() for l in lists: if l: q.put((l.val, l)) while not q.empty(): val, node = q.get() point.next = ListNode(val) point = point.next node = node.next if node: q.put((node.val, node)) return head.next