Merge k Sorted Lists

题目链接

Merge k Sorted Lists - LeetCode

注意点

  • 给出了链表是有序的

解法

解法一:暴力。用map收集所有链表的数据,然后排序生成新链表。时间复杂度O(kn)

/**
 * 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) {
        map<int,int> m;
        int max = -2147483648;
        int min = 2147483647;
        for(auto l:lists)
        {
            auto p = l;
            while(p != NULL)
            {
                if(p->val > max) max = p->val;
                if(p->val < min) min = p->val;
                if(m.count(p->val) == 0) m[p->val] = 1;
                else m[p->val]++;
                p = p->next;
            }
        }
        ListNode* ret = new ListNode(0);
        auto p = ret;
        for(auto i = min;i <= max;i++)
        {
            int temp = m.count(i);
            if(temp != 0)
            {
                temp = m[i];
                for(auto j = 0;j < temp;j++)
                {
                    p->next = new ListNode(i);
                    p = p->next;
                }
            }
        }
        return ret->next;
    }
};

解法二:分治法。比如6个链表,先合并14、25、36。然后合并13,最后和2合并即可。要用到Merge Two Sorted Lists的函数。时间复杂度O(nlogk)。

class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if (lists.size() == 0) return NULL;
        int n = lists.size();
        while (n > 1) 
        {
            int k = (n + 1) / 2;
            for (int i = 0; i < n / 2; i++) 
            {
                lists[i] = mergeTwoLists(lists[i], lists[i + k]);
            }
            n = k;
        }
        return lists[0];
    }
    
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* ans = new ListNode(0);
        ListNode* pointer = ans;
        while(l1 != NULL && l2 != NULL)
        {
            if(l1->val < l2->val)
            {
                pointer->next = l1;
                pointer = pointer->next;
                l1 = l1->next;
            }
            else
            {
                pointer->next = l2;
                pointer = pointer->next;
                l2 = l2->next;
            }
        }
        if(l1 != NULL)
        {
            pointer->next = l1;
        }
        if(l2 != NULL)
        {
            pointer->next = l2;
        }
        return ans->next;
    }
};

解法三:优先队列(或者叫最小堆)。参见[LeetCode] Merge k Sorted Lists 合并k个有序链表

小结

  • 暴力算法真是万能的!
原文地址:https://www.cnblogs.com/multhree/p/10356133.html