• 【Merge K Sorted Lists】cpp


    题目:

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

    代码:

    /**
     * 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.size()==0) return NULL;
            return Solution::mergeK(lists, 0, lists.size()-1);
        }
        static ListNode* mergeK(vector<ListNode*>& lists, int begin, int end )
        {
                if ( begin==end ) return lists[begin];
                if ( (begin+1)==end ) return Solution::mergeTwo(lists[begin], lists[end]);
                int mid = ( begin + end ) / 2;
                ListNode *firstHalf = Solution::mergeK(lists, begin, mid);
                ListNode *secondHalf = Solution::mergeK(lists, mid+1, end);
                return Solution::mergeTwo(firstHalf, secondHalf);
        }
        static ListNode* mergeTwo( ListNode *h1, ListNode *h2 )
        {
                ListNode dummy(-1);
                ListNode *p = &dummy;
                while ( h1 && h2 ){
                    if ( h1->val<h2->val ){
                        p->next = h1;
                        h1 = h1->next;
                    }
                    else{
                        p->next = h2;
                        h2 = h2->next;
                    }
                    p = p->next;
                }
                p->next = h1 ? h1 : h2;
                return dummy.next;
        }
    };

    tips:

    多路归并写法。

    =================================================

    第二次过这道题,第一次没有写成归并的形式,结果超时了。

    在网上查了一下这道题的时间复杂度分析:http://www.cnblogs.com/TenosDoIt/p/3673188.html

    改成了归并的写法,AC了。

    /**
     * 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)
            {
                return Solution::divide(lists, 0, lists.size()-1);
            }
            ListNode* divide(vector<ListNode*>& lists, int begin, int end)
            {
                if ( begin>end ) return NULL;
                if ( begin==end ) return lists[begin];
                int mid = (begin+end)/2;
                ListNode* l = Solution::divide(lists, begin, mid);
                ListNode* r = Solution::divide(lists, mid+1, end);
                return Solution::merge2Lists(l, r);
            }
            static ListNode* merge2Lists(ListNode* p1, ListNode* p2)
            {
                ListNode head(0);
                ListNode* p = &head;
                while ( p1 && p2 )
                {
                    if ( p1->val < p2->val )
                    {
                        p->next = p1;
                        p1 = p1->next;
                    }
                    else
                    {
                        p->next = p2;
                        p2 = p2->next;
                    }
                    p = p->next;
                }
                p->next = p1 ? p1 : p2;
                return head.next;
            }
    };

     用非递归又写了一个。

    /**
     * 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 NULL; 
                int length = lists.size();
                while ( length>1 )
                {
                    int index = 0;
                    int i=1;
                    for ( ; i<length; i=i+2)
                    {
                        lists[index++] = Solution::merge2Lists(lists[i], lists[i-1]);
                    }
                    if ( length & 1 ) lists[index++] = lists[i-1]; 
                    length = index;
                }
                return lists[0];
            }
            static ListNode* merge2Lists(ListNode* p1, ListNode* p2)
            {
                ListNode head(0);
                ListNode* p = &head;
                while ( p1 && p2 )
                {
                    if ( p1->val < p2->val )
                    {
                        p->next = p1;
                        p1 = p1->next;
                    }
                    else
                    {
                        p->next = p2;
                        p2 = p2->next;
                    }
                    p = p->next;
                }
                p->next = p1 ? p1 : p2;
                return head.next;
            }
    };

    =====================================================

    之前两次过这道题,即使看了上面提到blog的解释,也没太直观理解为什么归并的效率高。

    第三次过,有点儿顿悟了:其实就是插入排序和归并排序的效率区别;只不过这次归并的是链表

  • 相关阅读:
    oracle索引
    linux命令
    struts2的配置文件struts.xml详解
    oracle删除一个表中的重复数据,且只保留一条
    初步研究java类的加载机制
    java读取Properties配置文件
    利用oracle闪回来找回被drop的表
    快速排序Quicksort
    树与树的概念
    递归
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4512861.html
Copyright © 2020-2023  润新知