1. 程式人生 > >leetcode 21. Merge Two Sorted Lists(23. Merge k Sorted Lists)

leetcode 21. Merge Two Sorted Lists(23. Merge k Sorted Lists)

21. Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

 

按照某種規則合併兩種列表的解法:

常規解法:定義一個假頭,之後的內容為結果。按從前至後順序完成歸併排序操作。

 public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode fakeNode= new ListNode(-1),cur= fakeNode;
        while(l1!=null || l2!=null){
            if(l1==null){cur.next=l2;  break;}
            if(l2==null){cur.next=l1;   break;}
            if(l1.val< l2.val){
                cur.next= l1;
                l1=l1.next;
            }
            else{
                cur.next=l2;
                l2=l2.next;
            }
            cur=cur.next;
        }
        return fakeNode.next;
    }

遞迴解法:(該方法棧空間消耗大,不適合大數量資料集)

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null)    return l2;
        if(l2==null)    return l1;
        if(l1.val< l2.val){
            l1.next= mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next= mergeTwoLists(l1,l2.next);
            return l2;
        }
    }

23. 

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

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

優先佇列解法:(需自行構造比較器)

public ListNode mergeKLists(ListNode[] lists) {
        ListNode fakeHead= new ListNode(-1), cur= fakeHead;
        if(lists==null || lists.length==0)   return fakeHead.next;
        PriorityQueue<ListNode> sortQueue= new PriorityQueue<>(valComparator);
        for(ListNode l: lists){
            if(l!=null)
                sortQueue.offer(l);
        }
        while(sortQueue.size()!= 0){
            cur.next= sortQueue.poll();
            if(cur.next.next!=null)
                sortQueue.offer(cur.next.next);
            cur= cur.next;
        }
        return fakeHead.next;
    }
    public static Comparator<ListNode> valComparator= new Comparator<ListNode>(){
        public int compare(ListNode l1, ListNode l2){
            return l1.val-l2.val;
        }
    };

divide and conquer解法:

由於是將k個連結串列按順序合成一個,可將k個連結串列對半分開,直至分的只剩一個或兩個為止,再合併。與歸併排序的思路是一樣的

public ListNode mergeKLists(ListNode[] lists) {
        ListNode res= new ListNode(-1);
        if(lists==null || lists.length==0)  return res.next;
        res.next= mergeListsCore(lists,0,lists.length-1);
        return res.next;
    }
    public ListNode mergeListsCore(ListNode[] lists, int start, int end){
        if(start== end)  return lists[start];
        if(start+1== end){
            return mergeTwoList(lists[start],lists[end]);
        }
        int mid= (start+end)/2;
        ListNode left= mergeListsCore(lists,start,mid);
        ListNode right= mergeListsCore(lists,mid+1,end);
        return mergeTwoList(left,right);
    }
    public ListNode mergeTwoList(ListNode l1, ListNode l2){
        ListNode fakeNode= new ListNode(-1),cur= fakeNode;
        while(l1!=null || l2!=null){
            if(l1==null){cur.next=l2;  break;}
            if(l2==null){cur.next=l1;   break;}
            if(l1.val< l2.val){
                cur.next= l1;
                l1=l1.next;
            }
            else{
                cur.next=l2;
                l2=l2.next;
            }
            cur=cur.next;
        }
        return fakeNode.next;
    }