Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
pro:将k个排好序的链表merge成一个有序链表,分析其复杂度
sol:
1.定义一个struct记录某个结点对应的链表的id,定义一个优先队列,每次将所有的链表表头和id信息入队列,O(log(k))的时间取出最小值。
2.将队首加到结果链表中,对应链表后移,如果没到链尾,加入。队列不为空的时候要继续这个操作。
每个节点都是如此添加到结果链表中的,因此时间复杂度是O(k*n*(log(k))),空间复杂度是优先队列的空间复杂度,O(k),在构造结果链表时不需要额外的空间的,这个代码里有用到,下次要优化。
code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
struct node//记录了一个节点对应的是哪个链表
{
int index;
ListNode *listnode;
node(int index,ListNode *ll):index(index),listnode(ll){}
};
struct cmp
{
bool operator()(node* bb,node* cc)
{
return bb->listnode->val>cc->listnode->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists)
{
priority_queue< node*,vector<node*>,cmp > myque;//定义优先队列
while(!myque.empty())
myque.pop();
int i;
ListNode *res = new ListNode(0);
ListNode *cur = res;
for(i=0;i<lists.size();i++)//将所有的表头插入到优先队列中
{
if(lists[i]!=NULL)
{
node* temp = new node(i,lists[i]);
myque.push(temp);
}
}
while(!myque.empty())//一直
{
node *ttop = myque.top();//找优先队列的队头
res->next = ttop->listnode;
res = res->next;
myque.pop();
if(lists[ttop->index]->next!=NULL)//如果这条链表没到最后的话
{
node *tt = new node(ttop->index,lists[ttop->index]->next);
lists[ttop->index] = lists[ttop->index]->next;//将选中的链表的表头后移
myque.push(tt);//并且选中链表的后面一个节点入队列
}
}
return cur->next;
}
};