LeetCode 23. Merge k Sorted Lists

来源:互联网 发布:网络3d游戏大全 编辑:程序博客网 时间:2024/06/03 19:10

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

有k个各自排好序的单链表,把它们合并成一个有序链表

这个题很明显的用归并排序思想可以解决,不过对时间的要求顺序比较高,直接用循环不容易达到时间限制要求。

方法1.每次从k个链表取表头作比较,拿到最小的那个,直到取到只剩一个链表,则完成比较,此方法最差的时间复杂度为O(n*k*k),n为单链表最大长度

方法2:每轮将链表数减少一半,最终合并为一个链表,时间复杂度为k/2*2n*log(k) = O(k*n*log(k))

方法3:还是用动态规划思想,把问题分成更小。

首先考虑合并两个链表l1,l2,MergeTwo(l1,l2)=MergeTwo(l1.next,l2) or MergeTwo(l1,l2.next);

然后mergeKLists(lists,0,k) = MergeTwo( mergeLists(0,2/k),mergeLists(k/2+1,k) );即把k个链表分为两个2/k,最后就可以用MergeTwo进行两个链表之间的合并排序.

AC的代码,在LeetCode的Java提交里面能够排在前15%。主要还是归功于直接操作原来的链表,只是占用栈空间,不需要额外new的开销。


public static ListNode mergeKLists(ListNode[] lists) {
if(lists==null || lists.length<1)return null;
int len = lists.length;

return partition(lists,0,len-1);
        
    }
public static ListNode partition(ListNode[] lists,int l,int r){
if(l==r)return lists[l];
if(l+1==r)return mergeTwo(lists[l],lists[r]);
int mid = (l+r)/2;
return mergeTwo(partition(lists,l,mid),partition(lists,mid+1,r));

}
    public static ListNode mergeTwo(ListNode l1,ListNode l2){
     if(l1==null && l2==null)
     return null;
     if(l1==null)return l2;
     if(l2==null)return l1;
     if(l1.val<=l2.val){
     l1.next = mergeTwo(l1.next,l2);
     return l1;
     }
     else{
     l2.next = mergeTwo(l1,l2.next);
     return l2;
     }
    
    
    }
    public static class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
  }

原创粉丝点击