• 23. Merge k Sorted Lists


    ▶ 合并 k 个已经排好序的单链表

    ● 代码,28 ms,二路归并递归版,时间复杂度 O(k n log k)

     1 class Solution
     2 {
     3 public:
     4     ListNode *mergeTwoLists(ListNode* l1, ListNode* l2)
     5     {
     6         if (l1 == nullptr)
     7             return l2;
     8         if (l2==nullptr)
     9             return l1;
    10         if (l1->val <= l2->val)
    11         {
    12             l1->next = mergeTwoLists(l1->next, l2);
    13             return l1;
    14         }
    15         else
    16         {
    17             l2->next = mergeTwoLists(l1, l2->next);
    18             return l2;
    19         }
    20     }
    21     ListNode *mergeKLists(vector<ListNode *> &lists)
    22     {
    23         if (lists.empty())
    24             return nullptr;
    25         int i, len;
    26         for (len = lists.size(); len > 1; len = (len + 1) / 2)
    27         {
    28             for (i = 0; i < len / 2; i++)
    29                 lists[i] = mergeTwoLists(lists[i], lists[len - 1 - i]);
    30         }
    31         return lists.front();
    32     }
    33 };

    ● 代码,30 ms,二路归并非递归版,时间复杂度 O(k n log k)

     1 class Solution
     2 {
     3 public:
     4     ListNode *mergeTwoLists(ListNode* l1, ListNode* l2)
     5     {
     6         ListNode  dummy(-1), *result = &dummy;
     7         for(;l1!=nullptr &&l2!=nullptr;)
     8         {
     9             if (l1->val <= l2->val)
    10             {
    11                 result->next = l1;
    12                 l1 = l1->next;
    13             }
    14             else
    15             {
    16                 result->next = l2;
    17                 l2 = l2->next;
    18             }
    19             result = result->next;
    20         }
    21         if (l1)
    22             result->next = l1;
    23         else if (l2)
    24             result->next = l2;
    25         return dummy.next;
    26     }
    27     ListNode *mergeKLists(vector<ListNode *> &lists)
    28     {
    29         if (lists.empty())
    30             return NULL;
    31         int i, len;
    32         for (len = lists.size(); len > 1; len = (len + 1) / 2)
    33         {
    34             for (i = 0; i < len / 2; i++)
    35                 lists[i] = mergeTwoLists(lists[i], lists[len - 1 - i]);            
    36         }
    37         return lists.front();
    38     }
    39 };

    ● 代码,29 ms,优先队列,最快的解法算法与之相同,时间复杂度 O(N log k)

     1 class Solution
     2 {
     3 public:
     4     struct compare
     5     {
     6         bool operator()(const ListNode* l, const ListNode* r)
     7         {
     8             return l->val > r->val;
     9         }
    10     };
    11     ListNode *mergeKLists(vector<ListNode *> &lists)
    12     {
    13         priority_queue<ListNode *, vector<ListNode *>, compare> q;
    14         ListNode *result, *tail;
    15         for (auto l : lists) // 把各单链表首元素加入优先队中
    16         {
    17             if (l)
    18                 q.push(l);
    19         }
    20         if (q.empty())
    21             return NULL;
    22         result = q.top(), q.pop();  // 取出头部
    23         if (result->next)           
    24             q.push(result->next);
    25         for (tail = result; !q.empty();)
    26         {
    27             tail->next = q.top(), q.pop();// 每次取出一个元素,若取出的元素有后继,则将后继加入优先队中
    28             tail = tail->next;
    29             if (tail->next)
    30                 q.push(tail->next);
    31         }
    32         return result;
    33     }
    34 };

    ● 代码,29 ms,使用堆,时间复杂度 O(N log k)

     1 class Solution
     2 {
     3 public:
     4     static bool heapComp(ListNode* a, ListNode* b)
     5     {
     6         return a->val > b->val;
     7     }
     8     ListNode* mergeKLists(vector<ListNode*>& lists)
     9     {
    10         ListNode head(0);
    11         ListNode *curNode = &head;
    12         vector<ListNode*> v;
    13         for (int i = 0; i<lists.size(); i++)
    14         {
    15             if (lists[i])
    16                 v.push_back(lists[i]);
    17         }
    18         make_heap(v.begin(), v.end(), heapComp);// 建堆
    19         for (;v.size()>0;)
    20         {
    21             curNode->next = v.front();
    22             pop_heap(v.begin(), v.end(), heapComp);
    23             v.pop_back();
    24             curNode = curNode->next;
    25             if (curNode->next)
    26             {
    27                 v.push_back(curNode->next);
    28                 push_heap(v.begin(), v.end(), heapComp);
    29             }
    30         }
    31         return head.next;
    32     }
    33 };
  • 相关阅读:
    用栈实现队列
    “非常规”的漏洞挖掘思路与技巧-请求参数加密,js接口- 漏洞定级评分的标准与关注点-违规测试标准详解
    【linux 文件管理】2-文件目录命令
    EHC
    kali linux高级渗透测试第七课
    maltego CE社区版-Domain与DNS name
    name servers-域名服务器
    【linux 文件管理】1-文件目录结构
    web应用安全自学指南
    kali linux高级渗透测试第六课
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/8379937.html
Copyright © 2020-2023  润新知