## leetcode23: Merge K sorted Lists

130 阅读1分钟

题目描述

合并 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;
}