Merge k Sorted Lists

来源:互联网 发布:c语言中break 编辑:程序博客网 时间:2024/06/14 00:00

Merge k Sorted Lists

My Submissions
Total Accepted: 55947 Total Submissions: 265405 Difficulty: Hard

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

Hide Tags
 Divide and Conquer Linked List Heap
Hide Similar Problems
 (E) Merge Two Sorted Lists (M) Ugly Number II
一.本人用STL中最小优先队列代码如下:
/** * 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() )return NULL;ListNode *head = new ListNode(-1);ListNode *List_cur = head;priority_queue<ListNode *, vector<ListNode *>, cmp> min_que;for( int i = 0; i < lists.size(); i++)if(lists[i])min_que.push( lists[i]);while( min_que.size()){List_cur->next = min_que.top();List_cur = List_cur->next;min_que.pop();if(  List_cur->next )min_que.push( List_cur->next );}head = head->next;return head;    }struct cmp{bool operator()( ListNode *a, ListNode *b ){return a->val > b->val;}};};
二.网上某同学用STL中堆代码如下:
//47msstruct CompareListElement {    bool operator ()(const ListNode* a, const ListNode* b) const    {        return (a->val > b->val);  //NOTE1: 用大于符号建立小堆    }};class Solution {public:    ListNode *mergeKLists(vector<ListNode *> &lists) {        vector<ListNode*> vecK;        ListNode* dummyHead = new ListNode(0);        ListNode* tail = dummyHead;        for (int i = 0; i < lists.size(); ++i) {            if (lists[i] != NULL) {//NOTE2: 判断是否为NULL                vecK.push_back(lists[i]);            }        }                std::make_heap(vecK.begin(), vecK.end(), CompareListElement()); //NOTE3.1 comparator 要么全部使用,要么全部不使用        while(!vecK.empty()) {            tail->next = vecK.front();            tail = tail->next;            std::pop_heap(vecK.begin(), vecK.end(), CompareListElement()); //NOTE3.2 comparator 要么全部使用,要么全部不使用            vecK.pop_back();            if(tail->next != NULL) {                vecK.push_back(tail->next);                std::push_heap(vecK.begin(), vecK.end(), CompareListElement()); //NOTE3.3 comparator 要么全部使用,要么全部不使用            }        }        return dummyHead->next;    }};

三.童鞋自己写的堆,代码如下:copy下学习
class Solution {public:    ListNode *mergeKLists(vector<ListNode *> &lists) {        // 使用堆排序,         // 1. 选出每个链表的头来插入小顶堆中,        // 2. 再把堆顶接入合并链表中,        // 3. 被选出的指针后移再加入小顶堆中,回到2        // 4. 最后所有链表都为空时,返回合并链表的头指针        if(lists.empty()) return nullptr;        vector<ListNode* > heap;        // 1. 选出每个链表的头来插入小顶堆中,        for(int i = 0; i != lists.size(); i ++){            if(lists[i]) heap.push_back(lists[i]);        }        makeHeap(heap);        // 2. 再把堆顶接入合并链表中,        ListNode head(-1); // 合并链表的表头        ListNode* p = &head;        while(!heap.empty()){            auto minNode = popHeap(heap);            p->next = minNode; // 接入链表            p = p->next;            // 3. 被选出的指针后移再加入小顶堆中,回到2            auto next = minNode->next;            if(next) pushHeap(heap, next);        }        // 4. 最后所有链表都为空时,返回合并链表的头指针        return head.next;    }    // 建立小顶堆    // 自低向上    void makeHeap(vector<ListNode*> &heap){        // 从最后一个元素的父节点开始建立小顶堆        for(int i = heap.size()/2; i >0 ; i --){            minHeap(heap, i);        }    }    // 调整小顶堆,以第i个元素为根建立小顶堆    //位置从1开始,取元素时记得-1    // 自顶向下    void minHeap(vector<ListNode*> &heap, int i){        int l = i*2;        int r = l+1;        int least(i);        // 算出最小元素的位置        if((l< heap.size()+1) && heap[l-1]->val<heap[i-1]->val ){            // 如果没有超过边界并且左孩子比父亲小,则换            least = l;        }        if(r<heap.size()+1 && heap[r-1]->val<heap[least-1]->val){            // 如果没有超过边界并且右孩子最小,则换            least = r;        }        if(least != i){            swap(heap[i-1], heap[least-1]);            minHeap(heap, least);        }    }    // 在小顶堆中插入一个元素    // 自低向上    void pushHeap(vector<ListNode*> &heap, ListNode* p){        heap.push_back(p);        int child = heap.size();        int parent = child/2;        for(int child = heap.size(),parent = child/2; parent; child--, parent = child/2){            if(heap[child-1]->val < heap[parent-1]->val){                swap(heap[child-1], heap[parent-1]);            }        }    }    // 弹出堆顶    ListNode* popHeap(vector<ListNode*> &heap){        swap(heap[0], heap[heap.size()-1]);        auto p = heap.back();        heap.pop_back();        minHeap(heap, 1);        return p;    }};



0 0