LeetCode 23.Merge k Sorted Lists 合併K個的有序鏈表

23.合併排序N個有序鏈表

23. Merge k Sorted Lists

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
直接合並

對每一個鏈表的的頭結點進行掃描,找出最小的節點,然後將其加入結果集裏面。然後指向該節點的指針進行後移。一直到最後面所有每一個鏈表的元素都遍歷完爲止。這樣有很多節點會被比較很多次。時間複雜度爲O(nk)。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0){
            return null;
        }
        ListNode first = new ListNode(0);
        ListNode p = first;
        while(true){            
            ListNode min = new ListNode(Integer.MAX_VALUE);
            int j;
            for(j = 0; j < lists.length; j++){
                if(lists[j] != null){
                    min = lists[j];
                    break;
                }
            }
            if(j == lists.length){
                break;
            }
            int minIndex = j;
            for(int i = j; i < lists.length; i++){
                if(lists[i] == null){
                    continue;
                }
                if(lists[i].val < min.val){
                    min = lists[i];
                    minIndex = i;
                }
            }
            p.next = min;
            
            lists[minIndex] = lists[minIndex].next;
            p = p.next;
            
        }
        return first.next;
    }
}
分治法

從本體我們可以採用分而治之的策略,將複雜的問題分解爲多個簡單的小問題。,其實合併k個鏈表可以分解爲合併兩個鏈表的問題。
這裏使用了一個offset來表示偏移量。舉個例子,假如有4個鏈表,我們就先合併(1,2),(3,4) 兩組鏈表然後合併爲1,3鏈表。這個時候偏移量就爲1,意識就是鏈表和與它合併的鏈表的距離。第二步就是合併(1,3)鏈表,此時的偏移量就爲2。偏移量是以2的N次方指數增長的。當全部鏈表合成完之後,結果就是第一個鏈表。這樣操作時間複雜度爲O(nlogk)。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0){
            return null;
        }
        
        for(int offset = 1; offset < lists.length; offset *= 2){
            for(int i = 0; i + offset < lists.length; i += offset * 2){
                lists[i] = mergeTwoLists(lists[i],lists[i+offset]);
            }
        }
        return lists[0];
    }
    
    public ListNode mergeTwoLists(ListNode l1, ListNode l2){        
        ListNode first = new ListNode(0);
        ListNode p = first;
        while(l1 != null && l2 != null){
            if(l1.val < l2.val){
                p.next = l1;
                l1 = l1.next;
                p = p.next;
            } else {
                p.next = l2;
                l2 = l2.next;
                p = p.next;
            }
        }
        if(l1 == null){
            p.next = l2;
        }
        if(l2 == null){
            p.next = l1;
        }
        return first.next;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章