您的位置:首页 > 职场人生

面试中常见链表问题2:合并k个有序链表

2016-06-06 09:36 681 查看
给定k个链表,把这k个链表合并为一个有序的链表。

方法一:(1)每次都需要合并两个有序的链表。(2)把上一次合并后的链表与当前要合并的链表再次合并,直到剩下一个链表为止。此方法时间复杂度太高。
//合并两个有序链表
ListNode *mergeTwoLists(ListNode *l1,ListNode *l2)
{
ListNode *head = new ListNode(0);
ListNode *p = head;
while(l1 != NULL && l2 != NULL)
{
if(l1->val < l2->val)
{
p->next = l1;
l1 = l1->next;
}
else
{
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
if(l1 != NULL)
{
p->next = l1;
}
if(l2 != NULL)
{
p->next = l2;
}
return head->next;
}

//合并k个有序链表
ListNode* mergeKLists(vector<ListNode*>& lists)
{
if(lists.empty())
return NULL;
for(int i = 1; i < lists.size(); ++i)
{
ListNode *head = mergeTwoLists(lists[0],lists[i]);
lists[0] = head;
}
return lists[0];
}
方法二:使用优先队列,每次从队头选择一个最小的元素插入到新的链表中。效果比方法一好。
//优先队列使用的比较函数
struct compare
{
bool operator()(ListNode *lhs,ListNode *rhs)
{
return lhs->val > rhs->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
if(lists.empty())
return NULL;
priority_queue<ListNode *,vector<ListNode *>,compare> q;
for(int i = 0; i < lists.size(); ++i)
{
if(lists[i] != NULL)
q.push(lists[i]);
}
if(q.empty())
return NULL;
ListNode *head = q.top();
q.pop();
ListNode *tail = head;
if(tail->next)
q.push(tail->next);
while(!q.empty())
{
tail->next = q.top();
q.pop();
tail = tail->next;
if(tail->next)
q.push(tail->next);
}
return head;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: