【Leetcode】Merge k Sorted Lists

来源:互联网 发布:linux基础命令 编辑:程序博客网 时间:2024/04/29 12:05

问题

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

代码

class Solution {public:    ListNode *mergeKLists(vector<ListNode *> &lists) {map<int, ListNode* >mymap;for (int i = 0 ; i < lists.size(); i++) {ListNode* node = lists[i];while (node) {ListNode* tempNode = node;node=node->next;ListNode *bufNode = mymap[tempNode->val];if(bufNode){tempNode->next =bufNode;}else{tempNode->next = NULL;}mymap[tempNode->val] = tempNode;}}map<int, ListNode* >::iterator beginiter = mymap.begin();map<int, ListNode* >::iterator enditer = mymap.end();ListNode *returnNode = NULL;ListNode *lastNode = NULL;for (; beginiter != enditer; beginiter++) {if (!beginiter->second) {continue;}if (!returnNode) {returnNode = beginiter->second;}if (lastNode) {lastNode->next = beginiter->second;}ListNode* equalNode = beginiter->second;while (equalNode->next) {equalNode = equalNode->next;}/* equalNode is the last one */lastNode = equalNode;}return returnNode;    }};


分析

方法1(超时):两个list做merge,然后反复,一直到最后一个。(这种很容易造成时间复杂度是 n^k 次方)
方法2(超时):优化方法1,利用merge_sort的思想,切半然后做merge,主要为了防止分布的太广。(这里只是侥幸心理,其实最坏时间复杂度依然会是n^k)
方法3(上面的方法)
网上有很多方法,貌似这题的争议比较大,我也和他们的完全不一样:
解释:
1. 首先,先由map来重新排列所有的list,把相同的放到一个节点下,且链接起来。
2. 然后遍历一遍,因为我已经证明map是从小到大排列的了《证明map从小到大传送门》,然后把list首尾链接起来就可以了。

看上去很简单,首先构建这个 map 的复杂度是 O(nklognk ), 然后遍历一遍为O(nk)。所以总的复杂度是O(nklognk).不过有浪费,空间应该是 nk(这里取决于map的实现&优化鸟,除去常数,应该也是nk).

总结

这题本来是考核链表的,最后被我做成排序了,蛮扯淡的。不过复杂度相对来说比较低了。
0 0