LeetCode 23. Merge k Sorted Lists

来源:互联网 发布:淘宝店模板收费吗 编辑:程序博客网 时间:2024/05/22 07:37
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
这道题如果有第21题 合并两个链表的基础就会比较容易,具体合并链表的时候有两种思路

(1)如果k个list依次连起来(l1先和l2连起来,结果再和l3连起来,依次),时间复杂度是 N*K*K 会超时,具体计算方法如下:假设有K个长度为N的list (l1,l2,l3...lK), 然后计算最差情况下的时间复杂度, 
l1+l2 ---> l12 最坏情况的操作是2N次
l12+l3 ---> l123 最坏情况下的操作是3N次
依次类推:最坏情况下总共操作:2N+3N+4N+...+kN = (2+k)*(k-1)*N/2 也就是N*K*K 的时间复杂度

(2)如果两两连起来,像归并排序那样处理,时间复杂度是N*K*logK 就不会超时;
假设有8个长度为N的list (l1,l2,...,l8),然后计算最差情况下的时间复杂度:
两两一组合并分三个阶段,第一阶段是8个长度为N的链表合并, 操作次数是2N*4
第二阶段是4个长度为2N的链表合并,操作次数是4N*2
第三阶段是2个长度为4N的链表合并,操作次数是8N*1
所以总共操作次数是 N*8*3
可以猜测出一半的结论是K个长度为N的list的时间复杂度是 N*K*logK

 
程序如下:
  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* mergeTwoLists(ListNode* l1, ListNode* l2) {
  12. ListNode* head= new ListNode(0);
  13. ListNode* p=head;//head->next为返回的指针
  14. while(1)
  15. {
  16. if(l1 && l2){
  17. if(l1->val<l2->val){
  18. p->next=l1;
  19. p=l1;
  20. l1=l1->next;
  21. }
  22. else{
  23. p->next=l2;
  24. p=l2;
  25. l2=l2->next;
  26. }
  27. }
  28. else if(l1 && l2==NULL){
  29. p->next=l1;
  30. break;
  31. }
  32. else if(l1==NULL && l2){
  33. p->next=l2;
  34. break;
  35. }
  36. else{
  37. break;
  38. }
  39. }
  40. return head->next;
  41. }
  42. ListNode* mergeKLists(vector<ListNode*>& lists) {
  43. if(lists.size()==0) return NULL;
  44. vector<ListNode*> old_lists;//合并前的lists
  45. vector<ListNode*> new_lists;//合并后的lists
  46. old_lists.clear();new_lists.clear();
  47. for(int i=0;i<lists.size();i++)
  48. old_lists.push_back(lists[i]);
  49. while(1)
  50. {
  51. if(old_lists.size()==1) break;//合并成一条链表就输出
  52. int cnt=0;
  53. for(int i=0;i<old_lists.size()/2;i++)
  54. {
  55. new_lists.push_back(mergeTwoLists(old_lists[cnt],old_lists[cnt+1]));
  56. cnt+=2;
  57. }
  58. if(cnt<old_lists.size())//如果链表数是奇数,则合并完前面的两两组合后,还要加入最后一个链表
  59. new_lists.push_back(old_lists[cnt]);
  60. old_lists.clear();
  61. for(int i=0;i<new_lists.size();i++)
  62. old_lists.push_back(new_lists[i]);
  63. new_lists.clear();
  64. }
  65. return old_lists[0];
  66. }
  67. };
0 0