LeetCode每日一题——23. 合并K个排序链表

160 阅读1分钟

23. 合并K个排序链表

第一个不看解答,就能做出的困难题。

题目:

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入: [

​ 1->4->5,

​ 1->3->4,

​ 2->6

​ ]

输出: 1->1->2->3->4->4->5->6

解析:

看到这个题目,我们很容意就想到归并排序比较像,解法就自然而然出来了。归并排序就是采用分治法,两两排序,最后合并到一起。

代码如下:

public ListNode mergeKLists(ListNode[] lists) {

  int size = lists.length;
  if(size == 0 ){
    return null;
  }

  return merge(lists,0,size-1,size);

}

private ListNode merge(ListNode[] lists,int start,int end,int size){

  if(size == 0 ){
    return null;
  }
  if(size ==1){
    return lists[start];
  }
  int mid = (start+end)/2;
  ListNode nl = merge(lists,start,mid,mid-start+1);
  ListNode nr = merge(lists,mid+1,end,end-mid);

  if(nl == null){
    return nr;
  }
  if(nr == null){
    return nl;
  }

  ListNode root = null;
  ListNode node = null;
  if(nl.val<= nr.val){
    root = nl;
    node = nl;
    nl = nl.next;
  }else{
    root = nr;
    node = nr;
    nr = nr.next;
  }

  while(nl != null && nr != null){
    if(nl.val<= nr.val){
      node.next = nl;
      node = node.next;
      nl = nl.next;
    }else{
      node.next = nr;
      node = node.next;
      nr = nr.next;
    }
  }
  if(nl!=null){
    node.next = nl;
  }
  if(nr!=null){
    node.next = nr;
  }
  return root;

}

复杂度分析

  • 时间复杂度:复杂度为 O(kn*logk)。k为链表数量,n为链表长度。
  • 空间复杂度:递归会使用到 O(logk) 空间代价的栈空间。