每日算法之二十一:Merge k Sorted Lists

来源:互联网 发布:java异常和错误的区别 编辑:程序博客网 时间:2024/06/10 01:25

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

函数原型如下:

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

给定一个向量(vector),存储的是每个链表的头指针。要求是把这k个有序链表合并成一个有序的链表输出。

我们可以采用分治法进行处理,分治法在算法结构上要求是能递归的。算法一次或者多次调用自身以解决紧密相关的子问题。

分支法就是将原问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题即可。然后再合并这些子问题的解合并出原问题的解。

分治模式在每层中递归时都有三个步骤,

分解:将原问题分解为子问题。分解n个待排序的链表成各有n/2个链表的子问题。

解决:解决子问题,递归的求解子问题,当然若子问题足够小(只有两个链表)就直接求解。使用递归,一次处理这两个子链表组。

合并:合并子问题的解为原问题的解。将两个链表合为一个链表,循环往复。

代码如下:

<span style="font-size:18px;">/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *mergeTwoList(ListNode *l1,ListNode *l2)    {//合并两个有序的链表,是在原空间上进行的指针操作,复杂度为O(n)        ListNode *helper = new ListNode(0);        ListNode *pre = helper;        helper->next = l1;//让要返回的链表直接连接到l1上,如果l1->val较小,则插入到l1前面        while(l1!=NULL && l2!=NULL)        {            if(l1->val>l2->val)            {                ListNode * p = l2;                l2 = l2->next;                p->next = pre->next;                pre->next = p;            }            else                 l1 = l1->next;            pre = pre->next;        }        if(l2!=NULL)//把最后剩下的l2全部链接到l1后面            pre->next = l2;        return helper->next;    }    ListNode *helper(vector<ListNode*> lists,int l,int h)    {        if(l<h)        {            int m = (l+h)/2;            return mergeTwoList(helper(lists,l,m),helper(lists,m+1,h));//合并子问题的解        }        return lists[l];    }    ListNode *mergeKLists(vector<ListNode *> &lists) {        if(lists.size() == 0)             return NULL;        return helper(lists,0,lists.size()-1);//求解子问题    }};</span>

下面给出使用堆排序方式的合并方法。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */struct cmp {    bool operator() (ListNode *a, ListNode *b) {        return a->val > b->val;    }};class Solution {public:    ListNode *mergeKLists(vector<ListNode *> &lists) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        priority_queue<ListNode *, vector<ListNode *>, cmp> queue;        for (int i = 0; i < lists.size(); i++) {            if (lists[i] != NULL) {                queue.push(lists[i]);            }        }                ListNode *head = NULL, *prev = NULL, *temp;        while (!queue.empty()) {            temp = queue.top();            queue.pop();            if (prev == NULL) {                head = temp;            }            else {                prev->next = temp;            }            prev = temp;                        if (temp->next != NULL) {                queue.push(temp->next);            }        }                return head;    }};



0 0
原创粉丝点击