zoukankan      html  css  js  c++  java
  • leetcode链表--17、merge-k-sorted-lists(合并k个已排序链表并排序输出)

    题目描述
     
    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
     
    解题思路:借鉴于合并两个排序链表的题,采用分治法来解决该问题
    不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和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         int n = lists.size();
    13         if(n == 0)
    14             return NULL;
    15  
    16         while(n > 1)
    17         {
    18             int k = (n+1)/2;
    19             for(int i=0;i<n/2;i++)
    20             {
    21                 lists[i] = merge2Lists(lists[i],lists[i+k]);
    22             }
    23             n = k;
    24         }
    25         return lists[0];
    26     }
    27     ListNode *merge2Lists(ListNode *l1, ListNode *l2)
    28     {
    29         ListNode *head = new ListNode(-1);
    30         ListNode *cur = head;
    31         while (l1 && l2)
    32         {
    33             if (l1->val < l2->val)
    34             {
    35                 cur->next = l1;
    36                 l1 = l1->next;
    37             }
    38             else
    39             {
    40                 cur->next = l2;
    41                 l2 = l2->next;
    42             }
    43             cur = cur->next;
    44         }
    45         if (l1) cur->next = l1;
    46         if (l2) cur->next = l2;
    47         return head->next;
    48     }
    49 };
    方法二:利用了最小堆这种数据结构,我们首先把k个链表的首元素都加入最小堆中,它们会自动排好序。然后我们每次取出最小的那个元素加入我们最终结果的链表中,然后把取出元素的下一个元素再加入堆中,下次仍从堆中取出最小的元素做相同的操作,以此类推,直到堆中没有元素了,此时k个链表也合并为了一个链表,返回首节点即可,代码如下:
     1 struct cmp {
     2     bool operator () (ListNode *a, ListNode *b) {
     3         return a->val > b->val;
     4     }
     5 };
     6   
     7 class Solution {  
     8 public:  
     9     ListNode *mergeKLists(vector<ListNode *> &lists) {  
    10         priority_queue<ListNode*, vector<ListNode*>, cmp> q;
    11         for (int i = 0; i < lists.size(); ++i) {
    12             if (lists[i]) q.push(lists[i]);
    13         }
    14         ListNode *head = NULL, *pre = NULL, *tmp = NULL;
    15         while (!q.empty()) {
    16             tmp = q.top();
    17             q.pop();
    18             if (!pre) head = tmp;
    19             else pre->next = tmp;
    20             pre = tmp;
    21             if (tmp->next) q.push(tmp->next);
    22         }
    23         return head;
    24     }  
    25 };
  • 相关阅读:
    ListCtr 每一行都加上选择框
    VC中MFC check box的用法
    第二章 掌握C++(2)C++的特性(上)
    第二章 掌握C++(1)从结构到类
    道路横断面设计
    第一章 Windows程序内部运行机制(5)动手编写一个Windows程序
    第一章 Windows程序内部运行机制(4)WinMain函数(续)
    将div旋转任意角度
    地址栏图标修改
    script 错误
  • 原文地址:https://www.cnblogs.com/qqky/p/6919802.html
Copyright © 2011-2022 走看看