合并K个有序链表
Posted 追逐面包和牛奶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并K个有序链表相关的知识,希望对你有一定的参考价值。
方法一:采用归并的思想将链表两两合并,再将两两合并后的链表做同样的操作直到合并为只有一个新的链表为止。
归类的时间复杂度是O(logn),合并两个链表的时间复杂度是O(n),则总的时间复杂度大概是O(nlogn)。
class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { if(lists.size()==0)return NULL; int n=lists.size();//n用来记录还有多少条链表需要合并 while(n>1){ int start=0; int end=n-1; while(start<end){ lists[start]=mergeTwoLists(lists[start++],lists[end--]); n--; } } return lists[0]; } ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { ListNode *head = new ListNode(-1); ListNode *cur = head; while (l1 && l2) { if (l1->val < l2->val) { cur->next = l1; l1 = l1->next; } else { cur->next = l2; l2 = l2->next; } cur = cur->next; } if (l1) cur->next = l1; if (l2) cur->next = l2; return head->next; } };
方法二:利用了最小堆这种数据结构,我们首先把k个链表的首元素都加入最小堆中,它们会自动排好序。然后我们每次取出最小的那个元素加入我们最终结果的链表中,然后把取出元素的下一个元素再加入堆中,下次仍从堆中取出最小的元素做相同的操作,以此类推,直到堆中没有元素了,此时k个链表也合并为了一个链表,返回首节点即可,代码如下:
struct cmp { bool operator () (ListNode *a, ListNode *b) { return a->val > b->val;//注意这里是a->val小的优先级高 } }; class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*, vector<ListNode*>, cmp> q; for (int i = 0; i < lists.size(); ++i) { if (lists[i]) q.push(lists[i]); } ListNode *head = NULL, *pre = NULL, *tmp = NULL; while (!q.empty()) { tmp = q.top(); q.pop(); if (!pre) head = tmp; else pre->next = tmp; pre = tmp; if (tmp->next) q.push(tmp->next); } return head; } };
以上是关于合并K个有序链表的主要内容,如果未能解决你的问题,请参考以下文章
小C秋招面试算法题:合并k个有序数组合并k个有序链表(分治思想)
小C秋招面试算法题:合并k个有序数组合并k个有序链表(分治思想)