合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6
思路:
这是一道困难难度的题目。 想法很容易想到,既然是每个ListNode都是递增有序列表,那么只需要每轮遍历一次整个vector<ListNode*>中每个链表的头节点,选出最小的节点,然后拼接到暂存链表的尾部即可。停止条件也很直观,当vector中所有ListNode链表均访问到尾部即停止。
第二个想法来自于合并两个有序链表这道题。如果序链表成对合并,那么vector<ListNode*>中有k个链表的话,第一轮合并会把它变成k/2个,第m轮合并即可把链表数量减少到\( \frac{k}{2^{m}}\) 个。
AC代码:
//非常慢的头节点扫描版 /** * 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 nullptr; ListNode* Result = new ListNode(-1); ListNode* RPresent = Result; ListNode* temp = GetPresentSmallestNumber(lists); while(temp) { if(temp != nullptr) { RPresent->next = temp; RPresent = RPresent->next; } temp = GetPresentSmallestNumber(lists); } return Result->next; } ListNode* GetPresentSmallestNumber(vector<ListNode*>& lists) { ListNode* t_Result = nullptr; int t_Length = lists.size(), t_FinishCounter = 0; int t_minValue = std::numeric_limits<int>::max(), t_minIndex = 0; for(int t_index = 0; t_index < t_Length; t_index++) { if(lists[t_index] != nullptr) { if(lists[t_index]->val < t_minValue) { t_minValue = lists[t_index]->val; t_minIndex = t_index; } } else { t_FinishCounter++; } } if(t_Length == t_FinishCounter) { t_Result = nullptr; } else { t_Result = lists[t_minIndex]; lists[t_minIndex] = lists[t_minIndex]->next; t_Result->next = nullptr; } return t_Result; } };
双有序链表合并直接用了我以前写的这篇文章的代码。
//快一些的链表两两合并版 /** * 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.size()< 1) return nullptr; if(lists.size()< 2) return lists[0]; vector<ListNode*> tempResult; while(lists.size() > 1) { for(unsigned int t_index = 0; (t_index < lists.size()) && (t_index + 1 < lists.size()); t_index += 2) { tempResult.push_back(mergeTwoLists(lists[t_index], lists[t_index + 1])); } if(lists.size() % 2 == 1) { tempResult.push_back(lists.back()); } lists = tempResult; tempResult.clear(); } return lists[0]; } ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(l1 == nullptr) { if(l2 == nullptr) return nullptr; else return l2; } else { if(l2 == nullptr) return l1; } //l1 != nullptr, l2 != nullptr ListNode dummyHeadNode(-10000); dummyHeadNode.next = l1; ListNode* cursor1 = &dummyHeadNode,* cursor2 = l2; while(cursor1 != nullptr && cursor1->next != nullptr && cursor2 != nullptr) { if(cursor1->val <= cursor2->val && cursor1->next->val > cursor2->val) { ListNode* temp = cursor2; cursor2 = cursor2->next; temp->next = cursor1->next; cursor1->next = temp; } cursor1 = cursor1->next; } if(cursor1->next == nullptr && cursor2 != nullptr) cursor1->next = cursor2; return dummyHeadNode.next; } };
Published by