23. 合併K個排序鏈表

合併 k 個排序鏈表,返回合併後的排序鏈表。請分析和描述算法的複雜度。
示例:
 
輸入:
[
  1->4->5,
  1->3->4,
  2->6
]
輸出: 1->1->2->3->4->4->5->6
 
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。
 
思路 1
將全部節點放到 vector 中,再排序vector,將節點相連
 1 bool cmp(const ListNode *a, const ListNode *b) {
 2     return a->val < b->val;
 3 }
 4 
 5 class Solution {
 6 public:
 7     ListNode* mergeKLists(vector<ListNode*>& lists) {
 8         vector<ListNode *> node_vec;
 9         for (int i = 0; i < lists.size(); ++i) {
10             ListNode *head = lists[i];
11             while (head) {
12                 node_vec.push_back(head);//所有節點都放到 vector
13                 head = head->next;
14             }
15         }
16         if (node_vec.size() == 0) {
17             return NULL;
18         }
19         sort(node_vec.begin(), node_vec.end(), cmp);//根據數據域排序
20         for (int i = 1; i < node_vec.size(); ++i) {
21             node_vec[i-1]->next = node_vec[i];//鏈接鏈表
22         }
23         node_vec.back()->next = NULL;
24         return node_vec[0];
25     }
26 };

 

思路 2
對 k 個鏈表進行分治,兩個鏈表就合併

 1 class Solution {
 2 private:
 3     ListNode* mergeTwoLists(ListNode *head1, ListNode *head2) {
 4         ListNode temp_head(0);
 5         ListNode *ptr = &temp_head;
 6         
 7         while (head1 && head2) {
 8             if (head1->val < head2->val) {
 9                 ptr->next = head1;
10                 head1 = head1->next;
11             } else {
12                 ptr->next = head2;
13                 head2 = head2->next;
14             }
15             ptr = ptr->next;
16         }
17         if (head1) {
18             ptr->next = head1;
19         }
20         if (head2) {
21             ptr->next = head2;
22         }
23         return temp_head.next;
24     }
25 public:
26     ListNode* mergeKLists(vector<ListNode*>& lists) {
27         if (lists.empty()) return NULL;
28         if (lists.size() == 1) return lists.front();
29         if (lists.size() == 2) return mergeTwoLists(lists.front(), lists.back());//兩個鏈表就合併
30         
31         int mid = lists.size()/2;
32         vector<ListNode *> sub1_list;//將鏈表分爲兩部分
33         vector<ListNode *> sub2_list;
34         for (int i = 0; i < mid; ++i) {
35             sub1_list.push_back(lists[i]);
36         }
37         for (int i = mid; i < lists.size(); ++i) {
38             sub2_list.push_back(lists[i]);
39         }
40         ListNode *l1 = mergeKLists(sub1_list);//接着分,直到兩部分鏈表全部節點都排好序
41         ListNode *l2 = mergeKLists(sub2_list);
42         
43         return mergeTwoLists(l1, l2);
44     }
45 };
相關文章
相關標籤/搜索