【原创】leetCodeOj --- Merge k Sorted Lists 解题报告

题目地址:

https://oj.leetcode.com/problems/merge-k-sorted-lists/

 

题目内容:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/

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

 

方法:

用最小堆来做就可以了。第一轮将链表所有头结点插入堆中,当堆非空时,弹出一个结点加入输出链表,若该结点有后继结点,则后继结点入堆。

 

复杂度分析:

设有k个链表,每个链表有n个结点。

则堆的大小最多为k。

每个结点都要入一次堆并出一次堆,入堆的复杂度为lgk,出堆时为了维护堆的性质复杂度也是lgk

一共有k * n个结点

所以,总的复杂度为O(k * n * lgk)

 

如果简单粗暴直接堆排序,那么堆的大小就是k * n,入堆出堆的复杂度就是lg(k * n),要大不少。

 

如果直接按归并排序那样简单粗暴的归并,那么每轮中获得获胜结点的复杂度是k,由于每轮只产生一个获胜结点,所以一共有 k * n轮,那么复杂度就是O(k * k * n)

 

AC代码:(直接手写heap,免得重载运算符)

class Solution {

    class MergeHeap
    {
        public:
            MergeHeap()
            {
                heap.push_back(NULL);
            }
            bool isEmpty()
            {
                return heap.size() <= 1; // 0号元素永远为NULL
            }
            void insert(ListNode *tmp)
            {
                if (tmp == NULL)
                    return;
                heap.push_back(tmp);
                mergeInsert();
            }
            ListNode *pop()
            {
                if (this->isEmpty())
                    return NULL;
                int last = heap.size() - 1;
                ListNode *tmp = heap[1];
                heap[1] = heap[last];
                heap.pop_back();
                if (!this->isEmpty())
                    mergeDelete(1);
                return tmp;
            }

        private:
            vector<ListNode *> heap;
            void mergeDelete(int start)
            {
                int last  = heap.size() - 1;
                ListNode *tmp = heap[start];    
                int lchild = start * 2;
                int rchild = start * 2 + 1;
                int target = 0; // marked win sub-tree
                if (lchild <= last && rchild <= last)
                {
                    target = heap[rchild]->val > heap[lchild]->val ? lchild : rchild;

                }
                else if (lchild <= last)
                {
                    target = lchild;
                }
                else if (rchild <= last)
                    target = rchild;
                if (target)
                {
                    if (heap[target]->val < heap[start]->val)
                    {
                        heap[start]  = heap[target];
                        heap[target] = tmp;
                        mergeDelete(target);
                    }                    
                }
                
            }
            void mergeInsert()
            {
                int last = heap.size() - 1;
                int pare = last / 2; 
                while (pare != 0)
                {
                    if (heap[pare]->val > heap[last]->val)
                    {
                        ListNode *tmp = heap[pare];
                        heap[pare] = heap[last];
                        heap[last] = tmp;
                    }
                    else
                        break;
                    last = pare;
                    pare /= 2;
                }
            }
    };
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        MergeHeap myheap;
        int len = lists.size();
        if (!len)
            return NULL;
        for (int i = 0;i < len;i++)
            myheap.insert(lists[i]);
        ListNode *head = NULL;
        ListNode *tmp  = NULL;
        ListNode *tail = NULL;
        while (!myheap.isEmpty())
        {
            tmp = myheap.pop();
            if (!head) // init output list.
            {
                head = tmp;
                tail = tmp;
            }
            else
            {
                tail->next = tmp;
                tail = tmp;
            }
            if (tmp->next)
            {
                myheap.insert(tmp->next);
            }

        }
        return head;
    }
};

 

posted on 2014-10-21 00:54  shadowmydx'sLab  阅读(144)  评论(0编辑  收藏  举报

导航