面试中常见链表问题2:合并k个有序链表
2016-06-06 09:36
681 查看
给定k个链表,把这k个链表合并为一个有序的链表。
方法一:(1)每次都需要合并两个有序的链表。(2)把上一次合并后的链表与当前要合并的链表再次合并,直到剩下一个链表为止。此方法时间复杂度太高。
//合并两个有序链表 ListNode *mergeTwoLists(ListNode *l1,ListNode *l2) { ListNode *head = new ListNode(0); ListNode *p = head; while(l1 != NULL && l2 != NULL) { if(l1->val < l2->val) { p->next = l1; l1 = l1->next; } else { p->next = l2; l2 = l2->next; } p = p->next; } if(l1 != NULL) { p->next = l1; } if(l2 != NULL) { p->next = l2; } return head->next; } //合并k个有序链表 ListNode* mergeKLists(vector<ListNode*>& lists) { if(lists.empty()) return NULL; for(int i = 1; i < lists.size(); ++i) { ListNode *head = mergeTwoLists(lists[0],lists[i]); lists[0] = head; } return lists[0]; }方法二:使用优先队列,每次从队头选择一个最小的元素插入到新的链表中。效果比方法一好。
//优先队列使用的比较函数 struct compare { bool operator()(ListNode *lhs,ListNode *rhs) { return lhs->val > rhs->val; } }; ListNode* mergeKLists(vector<ListNode*>& lists) { if(lists.empty()) return NULL; priority_queue<ListNode *,vector<ListNode *>,compare> q; for(int i = 0; i < lists.size(); ++i) { if(lists[i] != NULL) q.push(lists[i]); } if(q.empty()) return NULL; ListNode *head = q.top(); q.pop(); ListNode *tail = head; if(tail->next) q.push(tail->next); while(!q.empty()) { tail->next = q.top(); q.pop(); tail = tail->next; if(tail->next) q.push(tail->next); } return head; }
相关文章推荐
- IOS面试资料
- 面试中常见链表问题1:合并两个有序链表
- JAVA_基础面试题
- Android面试题二
- 程序员批注《语言学教程》——第三章 从语素到短语
- 脱颖而出! 面试英语的一些小技巧
- 程序员常会用到的软件有哪些
- js操作符类型转换大全(前端面试题之操作符)
- 总结前端面试过程中最容易出现的问题
- Freelancer自由工作离我们还有多远?
- 黑马程序员——Java基础---面向对象之多态抽象类接口
- 黑马程序员——Java基础---面向对象代码块和继承和this和super和重写和重载和final
- 面试题17:合并两个排序的链表
- Hibernate常见面试知识点
- JAVA程序员必看的15本书
- 软件工程师的职业规划
- 面试小问题
- 适合程序员的画图技法
- 适合程序员的画图技法
- 鸡汤君_一个老程序员的建议66