您的位置:首页 > 其它

leetcode题目 合并N个排序好的链表

2015-10-03 23:03 211 查看
题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

思路: 两种方法,第一种思路调用合并两个排序好链表的函数,时间效率O(kN),k是链表个数,N是所有链表节点总数。第二种思路采用一个最小堆,先将k的链表的头结点构造成一个最小堆,取出最小的元素,并将最小元素所在链表的下一个元素压入堆中。直至堆为空。时间效率O(Nlogk)。本文两种代码均实现了。

解法一: 容易理解,但是时间效率差。虽然在本地对数据量小的测试用例都通过了。但leetcode上本题的难度系数是困难,所以这种方法不会通过,结果是时间超限,

class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(!lists.size())
return NULL;

ListNode* phead=NULL;
for(auto i=lists.begin();i!=lists.end();++i)
{
phead=mergeTwoLists(phead,*i);
}
return phead;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
ListNode* pmerge=NULL;
if(l1->val<l2->val)
{
pmerge=l1;
pmerge->next=mergeTwoLists(l1->next,l2);
}
else
{
pmerge=l2;
pmerge->next=mergeTwoLists(l1,l2->next);
}
return pmerge;
}
};


解法二: 利用堆,时间效率好,代码如下

/**
* 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) {
vector<ListNode*> heap;
for(auto i=lists.begin();i!=lists.end();++i)
{
if(*i!=NULL)
heap.push_back(*i);
}

//若堆为空,表示所有链表都为空或者lists本身为空
if(!heap.size())
return NULL;

ListNode* head,*p;
make_heap(heap.begin(),heap.end(),greater);
pop_heap(heap.begin(),heap.end(),greater);
head=p=heap.back();
heap.pop_back();

//堆非空,取出最小结点,然后压入最小结点的下一个结点
while(heap.size())
{
if(p->next!=NULL)
{
heap.push_back(p->next);
push_heap(heap.begin(),heap.end(),greater);
}
pop_heap(heap.begin(),heap.end(),greater);
p->next=heap.back();
heap.pop_back();
p=p->next;
}
return head;
}

//本程序堆中存放的是指针,并且要实现最小堆,所以写一个简单的比较函数
static  bool greater(ListNode* l1,ListNode* l2)
{
if(l1->val>l2->val)
return true;
else
return false;
}
};


运行结果通过,并且击败了99.29%的代码有木有!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: