即合併K個有序的鏈表成一個有序的鏈表。
如:[[2,4,4],[3,3],[1,5]]返回[1,2,3,3,4,4,5]。數組
假設K個有序數組,共有N個元素。
第一種思路:依次比較各鏈表的最小值,取其中最小併入新鏈表中。如此反覆N次便可獲得結果。時間複雜度爲O(K*N),空間複雜度爲O(1)。
第二種思路:最小堆。取各鏈表的最小值時維持一個大小爲K的最小堆,每次取出堆中最小值併入新鏈表,並插入最小值所在鏈表的下一個元素。時間複雜度爲O(N*log(K)),空間複雜度爲O(K)。
第三種思路:二分歸併。每次合併兩個原鏈表成新鏈表,直至新鏈表爲一個。時間複雜度爲O(N*log(K)),空間複雜度爲O(1)。
如下是第三種思路的代碼。spa
typedef int _Type; typedef struct ListNode ListNode; class Solution { public: ListNode* mergeLists(ListNode* pa, ListNode* pb) { /*if (pa == pb) return pa;*/ if (pa == NULL) return pb; else if (pb == NULL) return pa; ListNode head(0), *p = &head; do { if (pa->val < pb->val) { p = p->next = pa; pa = pa->next; if (pa == NULL) { p->next = pb; break; } } else { p = p->next = pb; pb = pb->next; if (pb == NULL) { p->next = pa; break; } } } while (true); return head.next; } ListNode* mergeKLists(std::vector<ListNode*>& lists) { if (lists.empty()) return NULL; int right = lists.size() - 1; while (right > 0) { int end = (right + 1) / 2; for (int i = 0; i < end; ++i) { lists[i] = mergeLists(lists[i], lists[right - i]); } right /= 2; } return lists[0]; } };
主要應用了二分歸併思想。code