Merge K Sorted Lists (Leetcode 23)

外排序,及k路歸并算法是一個很重要的算法,大數據用也會用到。
http://shmilyaw-hotmail-com.iteye.com/blog/1776132

此題,準備用兩種方法來解。第一種是用Priority Queue, 簡單好想。注意用了c++ Lamda Function, 來定義pque的compare function。

ListNode *mergeKLists(vector<ListNode *> &lists) {
        // write your code here
        if(lists.empty()) return NULL;
        
        auto comp = [](const ListNode *l1, const ListNode *l2){
            return l1->val > l2->val;    
        };
        priority_queue<ListNode*, vector<ListNode*>, decltype(comp)> pque(comp);
        
        ListNode *dummy = new ListNode(0);
        ListNode *pre = dummy;
        
        for(ListNode* it : lists){
            if(it != NULL) pque.push(it);
        }
        while(!pque.empty()){
            ListNode *cur = pque.top(); pque.pop();
            pre->next = cur;
            pre = pre->next;
            if(cur->next) pque.push(cur->next);
        }
        pre = dummy->next;
        delete dummy;
        return pre;
    }

第二種是Divide and Conquer,這種難想一些, 但實現起來并不復雜。
我們把k個list從中間分一半,先合并上k/2 (0 - k/2), 再合并下k/2 (k/2+1 - k),最后再merge。對上一半,下一半也分別采用相同的方法,先切一半,再合起來。MergeSort的思想。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()) return NULL;
        int size = lists.size();
        return sortList(lists, 0, size-1);
    }
    
    ListNode *sortList(vector<ListNode*>& lists, int start, int end){
        if(start > end) return NULL;
        else if(start == end){
            return lists[start];
        }
        int mid = start + (end-start)/2;
        return merge(sortList(lists, start, mid), sortList(lists, mid+1, end));
    }
    
    ListNode *merge(ListNode *headA, ListNode *headB){
        if(!headA) return headB;
        else if(!headB) return headA;
        ListNode *dummy = new ListNode(0);
        ListNode *pre = dummy;
        while(headA && headB){
            if(headA->val < headB->val){
                pre->next = headA;
                headA = headA->next;
            }
            else{
                pre->next = headB;
                headB = headB->next;
            }
            pre = pre->next;
        }
        pre->next = headA ? headA : headB;
        pre = dummy->next;
        delete dummy;
        return pre;
    }
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,769評論 0 33
  • Ba la la la ~ 讀者朋友們,你們好啊,又到了冷鋒時間,話不多說,發車! 1.冒泡排序(Bub...
    王飽飽閱讀 1,815評論 0 7
  • 某次二面時,面試官問起Js排序問題,吾絞盡腦汁回答了幾種,深感算法有很大的問題,所以總計一下! 排序算法說明 (1...
    流浪的先知閱讀 1,208評論 0 4
  • 原題 合并k個排序鏈表,并且返回合并后的排序鏈表。嘗試分析和描述其復雜度。 樣例給出3個排序鏈表[2->4->nu...
    Jason_Yuan閱讀 451評論 0 0
  • 閨蜜發來信息,一直糾結不停,來咨詢我。 問要不要和那個準男朋友處下去。 了解一些情況,他們認識好多年,但是好多次準...
    SUI心a閱讀 223評論 0 0