题目链接

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

合并k个有序的链表,我们假设每个链表的平均长度是n。这一题需要用到合并两个有序的链表子过程

算法1

最傻的做法就是先1、2合并,12结果和3合并,123结果和4合并,…,123..k-1结果和k合并,我们计算一下复杂度。

1、2合并,遍历2n个节点

12结果和3合并,遍历3n个节点

123结果和4合并,遍历4n个节点

123..k-1结果和k合并,遍历kn个节点

总共遍历的节点数目为n(2+3+…+k) = n*(k^2+k-2)/2, 因此时间复杂度是O(n*(k^2+k-2)/2) = O(nk^2),代码如下:

  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. class Solution {
  10. public:
  11. ListNode *mergeKLists(vector<ListNode *> &lists) {
  12. if(lists.size() == 0)return NULL;
  13. ListNode*res = lists[0];
  14. for(int i = 1; i < lists.size(); i++)
  15. res = merge2list(res, lists[i]);
  16. return res;
  17. }
  18.  
  19. ListNode *merge2list(ListNode *head1, ListNode*head2)
  20. {
  21. ListNode node(0), *res = &node;
  22. while(head1 && head2)
  23. {
  24. if(head1->val <= head2->val)
  25. {
  26. res->next = head1;
  27. head1 = head1->next;
  28. }
  29. else
  30. {
  31. res->next = head2;
  32. head2 = head2->next;
  33. }
  34. res = res->next;
  35. }
  36. if(head1)
  37. res->next = head1;
  38. else if(head2)
  39. res->next = head2;
  40. return node.next;
  41. }
  42. };

算法2:利用分治的思想把合并k个链表分成两个合并k/2个链表的任务,一直划分,知道任务中只剩一个链表或者两个链表。可以很简单的用递归来实现。因此算法复杂度为T(k) = 2T(k/2) + O(nk),很简单可以推导得到算法复杂度为O(nklogk)

递归的代码就不贴了。下面是非递归的代码非递归的思想是(以四个链表为例):                   本文地址

1、3合并,合并结果放到1的位置

2、4合并,合并结果放到2的位置

再把1、2合并(相当于原来的13 和 24合并)

  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. ListNode *mergeKLists(vector<ListNode *> &lists) {
  13. int n = lists.size();
  14. if(n == 0)return NULL;
  15. while(n >1)
  16. {
  17. int k = (n+1)/2;
  18. for(int i = 0; i < n/2; i++)
  19. lists[i] = merge2list(lists[i], lists[i + k]);
  20. n = k;
  21. }
  22. return lists[0];
  23. }
  24.  
  25. ListNode *merge2list(ListNode *head1, ListNode*head2)
  26. {
  27. ListNode node(0), *res = &node;
  28. while(head1 && head2)
  29. {
  30. if(head1->val <= head2->val)
  31. {
  32. res->next = head1;
  33. head1 = head1->next;
  34. }
  35. else
  36. {
  37. res->next = head2;
  38. head2 = head2->next;
  39. }
  40. res = res->next;
  41. }
  42. if(head1)
  43. res->next = head1;
  44. else if(head2)
  45. res->next = head2;
  46. return node.next;
  47. }
  48. };

算法3:维护一个k个大小的最小堆,初始化堆中元素为每个链表的头结点,每次从堆中选择最小的元素加入到结果链表,再选择该最小元素所在链表的下一个节点加入到堆中。这样当堆为空时,所有链表的节点都已经加入了结果链表。元素加入堆中的复杂度为O(longk),总共有kn个元素加入堆中,因此,复杂度也和算法2一样是O(nklogk)

  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. private:
  12. struct cmp
  13. {
  14. bool operator ()(const ListNode *a, const ListNode *b)
  15. {
  16. return a->val > b->val;
  17. }
  18. };
  19. public:
  20. ListNode *mergeKLists(vector<ListNode *> &lists) {
  21. int n = lists.size();
  22. if(n == 0)return NULL;
  23. ListNode node(0), *res = &node;
  24. priority_queue<ListNode*, vector<ListNode*>, cmp> que;
  25. for(int i = 0; i < n; i++)
  26. if(lists[i])
  27. que.push(lists[i]);
  28. while(!que.empty())
  29. {
  30. ListNode * p = que.top();
  31. que.pop();
  32. res->next = p;
  33. res = p;
  34.  
  35. if(p->next)
  36. que.push(p->next);
  37. }
  38. return node.next;
  39. }
  40. };

【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3673188.html

LeetCode:Merge k Sorted Lists的更多相关文章

  1. LeetCode: Merge k Sorted Lists 解题报告

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  2. [LeetCode] Merge k Sorted Lists 合并k个有序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...

  3. LeetCode——Merge k Sorted Lists

    Discription: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its ...

  4. leetcode -- Merge k Sorted Lists add code

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [ ...

  5. LeetCode Merge k Sorted Lists (链表)

    题意 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  6. [Leetcode] Merge k sorted lists 合并k个已排序的链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思 ...

  7. Leetcode:Merge k Sorted Lists分析和实现

    题目大意是传入一个链表数组lists,每个链表都由若干个链接的链表结点组成,并且每个链表结点记录一个整数.题目保证传入的链表中的整数按从小到大进行排序. 题目要求我们输出一个新的链表,这个链表中应该包 ...

  8. LeetCode Merge k Sorted Lists 解决报告

    https://oj.leetcode.com/problems/merge-k-sorted-lists/ 归并K已经整理阵列,和分析算法的复杂. 解决报告:无论是不考虑优化,最简单的实现是要重新走 ...

  9. LeetCode —— Merge k Sorted Lists

    /* ** 算法的思路: ** 1.将k个链表的首元素进行建堆 ** 2.从堆中取出最小的元素,放到链表中 ** 3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空 */ #in ...

随机推荐

  1. jquery动态改变div宽度和高度

    效果体验:http://keleyi.com/keleyi/phtml/jquery/23.htm 完整代码: <!DOCTYPE html PUBLIC "-//W3C//DTD X ...

  2. [Javascript]利用当前时间生成yyyymmddhhmmss这样的字符串

    function pad2(n) { return n < 10 ? '0' + n : n } function generateTimeReqestNumber() { var date = ...

  3. 【代码笔记】iOS-UIView的placeholder的效果

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  4. 【iOS】在Swift中使用JSONModel

    前言 首先所有的Model还是使用oc来写——看到这一句是不是想关网页了- - #,在swift里面直接写一直报错所以就将就用oc来写了,这里主要是分享一下搭配Alamofire使用的经验. 声明 欢 ...

  5. UITableViewController和XML解析还有地图的简单结合

    然后我的代码就按照上面的这个顺序输出. #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interfa ...

  6. android:使用Messenger进行进程间通信(二)

    //继续完善音乐播放器demo 相关文章: android:使用Messenger进行进程间通信(一):http://www.cnblogs.com/happyhacking/p/5318418.ht ...

  7. zDiaLog弹出层

    zDiaLog弹出层  立即下载 插件描述:zDiaLog弹出层 弹出框: 代替window.open.window.alert.window.confirm:提供良好的用户体验: 水晶质感,设计细腻 ...

  8. DDD实施经验分享—价值导向、从上往下进行(圈内第一个吃螃蟹DDD实施方案)

    阅读目录: 1.背景 2.从业务开始 3.从战略到战术 4.借助外力推动研发(QA.领导.自动化测试) 5.领域模型与SAAS平台的内核(价值最大化) 6.最后 1.背景 DDD本身的技术就不介绍了, ...

  9. WPF 自定义Expander

    自定义Exander,收缩侧边栏 样式如下 <Grid> <Grid.Resources> <ControlTemplate x:Key="ExpanderCo ...

  10. android break 与 return 的区别

    break 的含义是中断,return 的含义是结束整个方法的执行. 区别. public static void main(String agrs[]){ int i; for(i=0;i<1 ...