LeetCode No.23 Merge k Sorted Lists

来源:互联网 发布:世界遗产地理杂志淘宝 编辑:程序博客网 时间:2024/06/07 11:32

这一题是说要合并k个有序链表,显然可以借助合并两个有序链表来做,问题的关键是时间复杂度!

两个链表的合并操作时间复杂度为O(m + n),其中m和n为两个链表的长度,那么直观来讲,k个链表,如果我们一次将每个链表都合并到第一个链表,那么时间复杂度将是O(kn1 + (k - 1)n2 + (k - 2)n3 + ... + nk),这复杂度很高!

我们发现上述方法中l1被遍历了多达k次,这究竟是不是有必要呢?完全没有,我们完全可以两个两个的合并链表,这样时间复杂度将下降为O(logk(n1 + n2 + ... + nk)),相比于前面的方法下降了很多,如果每个链表长度相同,我们就可以发现前一种是O(k ^ 2),而后一种仅为O(logk)!

下面是代码,同样时刻牢记代码的鲁棒性!

  • 注意当lists为空时,程序在最后的返回语句处会出现未定义行为(我们不能访问一个空数组里的元素),因此要先加上判断语句!

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists)     {        if(lists.empty()) return nullptr;                int sz = lists.size();        //将链表组中的链表两个两个的合并        while(sz > 1)        {            for(int i = 0; i < sz / 2; ++i)                lists[i] = merge2Lists(lists[i], lists[sz - i - 1]);            sz = (sz + 1) >> 1;        }                return lists[0];    }    private:    ListNode *merge2Lists(ListNode *l1, ListNode *l2)    {        ListNode head = ListNode(0);        ListNode *curr = &head;        while(l1 != nullptr || l2 != nullptr)        {            if(!l1) {curr->next = l2, l2 = l2->next;}            else if(!l2) {curr->next = l1, l1 = l1->next;}            else            {                l1->val < l2->val ?                    (curr->next = l1, l1 = l1->next) : (curr->next = l2, l2 = l2->next);            }            curr = curr->next;        }                return head.next;    }};

下面是运行结果:


原创粉丝点击