分析
算法1:
类似于归并排序,将Merge k 个的问题,拆分成Merge 2 个的子任务,然后递归回溯。
算法复杂度 O(nlogn)
算法2:
使用最小堆。
维护一个最大 大小 k 的最小堆,每次从堆顶pop出元素放到结果中,并将该元素的next(如果有)push到最小堆中。最小堆构建O(klogk),然后所有的元素都要被插入最小堆,pop耗时O(1)。所以算法时间复杂度 O(nklogk):n,list最长为n;最小堆最大为k。
代码
方法一:
假设总共有k个list,每个list的最大长度是n,那么运行时间满足递推式T(k) = 2T(k/2)+O(n*k)。空间复杂度的话是递归栈的大小O(logk)。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */classSolution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {        if(lists.size() == 0)            returnNULL;        returnhelper(lists, 0, lists.size() - 1);    }    ListNode * helper(vector<ListNode*> &lists, intl, intr){        if(l < r){            intm = (l + r) >> 1;            returnmergeTwoLists(helper(lists,l,m), helper(lists,m+1,r));        }        returnlists[l];    }    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        ListNode tmp(INT_MIN);        ListNode * l3 = &tmp;        while(l1 && l2){            if(l1 -> val > l2 -> val){                l3 -> next = l2;                l2 = l2 -> next;            }            else{                l3 -> next = l1;                l1 = l1 -> next;            }            l3 = l3 -> next;        }        l3 -> next = l1 == NULL? l2 : l1;                 returntmp.next;    }}; | 
方法二:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */classSolution {public:    structMycompare{        booloperator()(ListNode * a, ListNode * b){            returna->val > b->val;        }    };    ListNode* mergeKLists(vector<ListNode*>& lists) {        priority_queue<ListNode *, vector<ListNode*>, Mycompare> min_heap;        for(auto l : lists) {            if(l)  min_heap.push(l);        }        if(min_heap.empty()) returnNULL;                ListNode result(0);        ListNode * tmp = &result;        while(!min_heap.empty()){            tmp->next = min_heap.top();            tmp = tmp->next;            min_heap.pop();            if(tmp->next != NULL){                min_heap.push(tmp->next);            }        }                returnresult.next;            }}; |