【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;

    }



};

 

你可能感兴趣的:(LeetCode)