赞
踩
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
1.优先队列
priority_queue的典型题目,几行就能搞定,但是需要注意lists里可能包含nullptr的情况。
我们需要维护当前每个链表没有被合并的元素的最前面一个,k 个链表就最多有 k 个满足这样条件的元素,每次在这些元素里面选取 val 属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这个过程。
2.递归法则
3.分治法
官方的分治合并
1.优先队列
2.分治思想
1.优先队列
class Solution { public: struct Status { int val; ListNode *ptr; bool operator < (const Status &rhs) const { return val > rhs.val; } }; priority_queue <Status> q; ListNode* mergeKLists(vector<ListNode*>& lists) { for (auto node: lists) { if (node) q.push({node->val, node}); } ListNode head, *tail = &head; while (!q.empty()) { auto f = q.top(); q.pop(); tail->next = f.ptr; tail = tail->next; if (f.ptr->next) q.push({f.ptr->next->val, f.ptr->next}); } return head.next; } };
2.递归法(java)
class Solution { public ListNode mergeKLists(ListNode[] lists) { if(lists.length==0)return null; return merge(lists,0,lists.length-1); } private ListNode merge(ListNode[] nodes,int l,int r){ if(l==r)return nodes[l]; int m=(l+r)/2; return merge2List(merge(nodes,l,m),merge(nodes,m+1,r)); } private ListNode merge2List(ListNode l1,ListNode l2){ if(l1==null || l2==null) return l2==null?l1:l2; ListNode res=l1.val>l2.val?l2:l1; res.next=merge2List(res.next,l1.val<=l2.val?l2:l1); return res; } }
3.分治
//java class Solution { public ListNode mergeKLists(ListNode[] lists){ if(lists.length == 0) return null; if(lists.length == 1) return lists[0]; if(lists.length == 2){ return mergeTwoLists(lists[0],lists[1]); } int mid = lists.length/2; ListNode[] l1 = new ListNode[mid]; for(int i = 0; i < mid; i++){ l1[i] = lists[i]; } ListNode[] l2 = new ListNode[lists.length-mid]; for(int i = mid,j=0; i < lists.length; i++,j++){ l2[j] = lists[i]; } return mergeTwoLists(mergeKLists(l1),mergeKLists(l2)); } public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode head = null; if (l1.val <= l2.val){ head = l1; head.next = mergeTwoLists(l1.next, l2); } else { head = l2; head.next = mergeTwoLists(l1, l2.next); } return head; } }
官方的分治法
class Solution { public: ListNode* mergeTwoLists(ListNode *a, ListNode *b) { if ((!a) || (!b)) return a ? a : b; ListNode head, *tail = &head, *aPtr = a, *bPtr = b; while (aPtr && bPtr) { if (aPtr->val < bPtr->val) { tail->next = aPtr; aPtr = aPtr->next; } else { tail->next = bPtr; bPtr = bPtr->next; } tail = tail->next; } tail->next = (aPtr ? aPtr : bPtr); return head.next; } ListNode* merge(vector <ListNode*> &lists, int l, int r) { if (l == r) return lists[l]; if (l > r) return nullptr; int mid = (l + r) >> 1; return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r)); } ListNode* mergeKLists(vector<ListNode*>& lists) { return merge(lists, 0, lists.size() - 1); } };
1.优先队列的复杂度
2.分治的复杂度
3.顺序合并的复杂度
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。