合并 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 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 10 /*class Solution { 11 public: 12 //法1 使用优先队列 小顶堆 13 //有k个待排序的链表 每次将未合并完的链表的头结点 放入优先队列 14 //然后再从优先队列中取出最小的 以尾插法放到res中 15 //最多操作kn次 每次从优先队列存入取出复杂度为logk 16 //总时间复杂度为 o(knlogk) 空间o(k) 17 struct Cell 18 { 19 ListNode* node; 20 Cell(ListNode* _node):node(_node){}; 21 bool operator <(const Cell& c)const 22 { 23 return node->val>c.node->val; 24 } 25 }; 26 ListNode* mergeKLists(vector<ListNode*>& lists) { 27 28 priority_queue<Cell> pq; 29 for(auto list:lists) 30 if(list) 31 pq.push(list); 32 ListNode* dummy=new ListNode(0),*tail=dummy; 33 while(!pq.empty()) 34 { 35 ListNode* temp=pq.top().node; 36 pq.pop(); 37 if(temp->next) 38 pq.push(temp->next); 39 tail->next=temp; 40 tail=temp; 41 } 42 return dummy->next; 43 } 44 };*/ 45 46 class Solution { 47 public: 48 //法2 分治合并 时o(knlogk) 空o(logk) 49 ListNode* merge2Lists(ListNode* a,ListNode* b) 50 { 51 ListNode dummy,*tail=&dummy,*pa=a,*pb=b; 52 //ListNode *dummy=new ListNode(); 53 //头节点使用ListNode类型不用ListNode* new 这样更省内存 54 while(pa&&pb) 55 { 56 if(pa->val<pb->val) 57 { 58 tail->next=pa; 59 pa=pa->next; 60 } 61 else 62 { 63 tail->next=pb; 64 pb=pb->next; 65 } 66 tail=tail->next; 67 } 68 tail->next=pa?pa:pb; 69 return dummy.next; 70 } 71 ListNode* merge(vector<ListNode*> &lists,int l,int r) 72 { 73 if(l==r)return lists[l]; 74 else if(l>r)return NULL; 75 int mid=(l+r)>>1; 76 return merge2Lists(merge(lists,l,mid),merge(lists,mid+1,r)); 77 } 78 ListNode* mergeKLists(vector<ListNode*>& lists) { 79 return merge(lists,0,lists.size()-1); 80 } 81 };