即合并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