【Leetcode】23. 合併 k 個有序鏈表(Merge k Sorted Lists)

Leetcode - 23 Merge k Sorted Lists (Hard)

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

解題思路:這道題類似之前的合併兩個有序鏈表,可以逐個兩兩合併,也可以每次取出鏈表頭部的最小節點,我也是首先想到這種方法,但是效率有點低。能夠通過優先級隊列和分治進行優化。

解法一:優先級隊列

public ListNode mergeKLists(ListNode[] lists) { 
    if (lists == null || lists.length == 0) return null;
    
    PriorityQueue<ListNode> queue= new PriorityQueue<ListNode>(lists.length,new Comparator<ListNode>(){
        @Override
        public int compare(ListNode o1,ListNode o2){
            if (o1.val<o2.val)
                return -1;
            else if (o1.val==o2.val)
                return 0;
            else 
                return 1;
        }
    });
    
    ListNode dummy = new ListNode(0);
    ListNode tail=dummy;
    
    for (ListNode node:lists)
        if (node!=null)
            queue.add(node);
        
    while (!queue.isEmpty()){
        tail.next=queue.poll();
        tail=tail.next;
        
        if (tail.next!=null)
            queue.add(tail.next);
    }
    return dummy.next;
}

解法二:分治

public static ListNode mergeKLists(ListNode[] lists){
    return partion(lists,0,lists.length-1);
}

public static ListNode partion(ListNode[] lists,int s,int e){
    if(s==e)  return lists[s];
    if(s<e){
        int q=(s+e)/2;
        ListNode l1=partion(lists,s,q);
        ListNode l2=partion(lists,q+1,e);
        return merge(l1,l2);
    }else
        return null;
}

// 合併兩個鏈表
public static ListNode merge(ListNode l1,ListNode l2){
    if(l1==null) return l2;
    if(l2==null) return l1;
    if(l1.val<l2.val){
        l1.next=merge(l1.next,l2);
        return l1;
    }else{
        l2.next=merge(l1,l2.next);
        return l2;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章