【leetcode】Merge k Sorted Lists

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

思路:

我自己的,每次找k个元素的最小的接在答案链表的后面。结果超时了。

    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.size() == 0) 
            return NULL;
        else if(lists.size() == 1)
            return lists[0];
        else
        {
            int n = lists.size();
            ListNode * ans = NULL;
            ListNode * anshead = NULL;
            vector<ListNode *> cur = lists;
            for(int i = 0; i < cur.size(); i++) //把链表是NULL的删掉
            {
                if(cur[i] == NULL)
                {
                    cur.erase(cur.begin() + i);
                    i--;
                    n--;
                }
            }
            while(n > 1) //每次把链表剩下的是NULL的删掉,剩下的链表只要多于1个就继续
            {
                int min = getmin(cur);
                if(ans == NULL) //头结点特别处理
                {
                    ans = cur[min];
                    anshead = ans;
                }
                else //其他结点处理
                {
                    ans->next = cur[min];
                    ans = ans->next;
                }
                cur[min] = cur[min]->next;
                if(cur[min] == NULL) //如果空了 删除
                {
                    cur.erase(cur.begin() + min);
                    n--;
                }
                ans->next = NULL;
            }
            if(!cur.empty()) //最后如果还有剩下的加在答案链表最后
            {
                if(ans == NULL)
                {
                    ans = cur[0];
                    anshead = ans;
                }
                else
                {
                    ans->next = cur[0];
                }
            }
            return anshead;
        }
    }

    int getmin(vector<ListNode *> cur)
    {
        int min = 0;
        for(int i = 0; i < cur.size(); i++)
        {
            if(cur[i]->val < cur[min]->val)
                min = i;
        }
        return min;
    }

看其他人的思路,发现只需要把相邻的链表两两合并就可以。速度还很快,只要33ms

 class Solution {
        struct CompareNode {
            bool operator()(ListNode* const & p1, ListNode* const & p2) {
                // return "true" if "p1" is ordered before "p2", for example:
                return p1->val > p2->val;
               //Why not p1->val <p2->val; ??
            }
        };
    public:
        ListNode *mergeKLists(vector<ListNode *> &lists) {

            ListNode dummy(0);
            ListNode* tail=&dummy;

            priority_queue<ListNode*,vector<ListNode*>,CompareNode> queue;

            for (vector<ListNode *>::iterator it = lists.begin(); it != lists.end(); ++it){
                if (*it)
                queue.push(*it);
            }
            while (!queue.empty()){
                tail->next=queue.top();
                queue.pop();
                tail=tail->next;

                if (tail->next){
                    queue.push(tail->next);
                }
            }

            return dummy.next;
        }
    };

还有一种用堆的方法,没有仔细看,记录下来,里面关于堆的使用以后可能有用。

class Solution {

public:

    ListNode *mergeKLists(vector<ListNode *> &lists) {

        // Begin and end of our range of elements:
        auto it_begin = begin(lists);
        auto it_end = end(lists);

        // Removes empty lists:
        it_end = remove_if(it_begin, it_end, isNull);
        if (it_begin == it_end) return nullptr; // All lists where empty.

        // Head and tail of the merged list:
        ListNode *head = nullptr;
        ListNode *tail = nullptr;

        // Builds a min-heap over the list of lists:
        make_heap(it_begin, it_end, minHeapPred);

        // The first element in the heap is the head of our merged list:
        head = tail = *it_begin;

        while (distance(it_begin, it_end) > 1) {

            // Moves the heap's front list to its back:
            pop_heap(it_begin, it_end, minHeapPred);

            // And removes one node from it:
            --it_end;
            *it_end = (*it_end)->next;

            // If it is not empty it inserts it back into the heap:
            if (*it_end) {

                ++it_end;
                push_heap(it_begin, it_end, minHeapPred);
            }

            // After  the push we have our next node in front of the heap:
            tail->next = *it_begin;
            tail = tail->next;
        }

        return head;
    }

private:

    // Predicate to remove all null nodes from a vector:
    static bool isNull(const ListNode* a) {

        return a == nullptr;
    }

    // Predicate to generate a min heap of list node pointers:
    static bool minHeapPred(const ListNode* a,
                            const ListNode* b) {

        assert(a);
        assert(b);

        return a->val > b->val;
    }

};
原文地址:https://www.cnblogs.com/dplearning/p/4220006.html