您的位置:首页 > 其它

Merge k Sorted Lists——分治与堆排序(需要好好看)

2015-09-02 11:45 302 查看
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

1,类似于Merge Sort的方法做k-1次,每次合并两个,但是这种方法超时.

for(int i = 1; i < lists.size(); i++)
head = merge(head, lists[i]);


2,分治法,合并的时间复杂度O(logN),不用递归,空间复杂度O(1)

思想很简单,两两合并之后在两两合并。

/**
* 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) {
int n = lists.size();
if (n == 0)  return NULL;
while (n > 1) {
int k = (n + 1) / 2;
for (int i = 0; i < n / 2; i++)
lists[i] = mergeTwoLists(lists[i], lists[i + k]);
n = k;
}
return lists[0];
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
ListNode *dummy = new ListNode(-1);
ListNode *p = dummy;
while(l1 != NULL && l2 != NULL) {
if(l1->val > l2->val) {
p->next = l2;
l2 = l2->next;
}else {
p->next = l1;
l1 = l1->next;
}
p = p->next;
}
if(l1 == NULL) {
p->next = l2;
}else if(l2 == NULL) {
p->next = l1;
}
return dummy->next;
}
};


  

3 关于堆排序(http://blog.csdn.net/yeruby/article/details/45154633)

这里使用STL的priorit_queue,它是优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序,

每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储。例如:我们常用的操作就是对数据排序,优先队列默认的是数据大的优

先级高。所以我们无论按照什么顺序push一堆数,最终在队列里总是top出最大的元素,所以这里我们需要改成小顶堆。

该算法维护一个大小为k的堆,每次都会取堆顶的最小元素放到结果中,然后读取该元素的下一个元素(若为空,跳过)放入堆中,重新维护好。因为

每个链表是有序的,每次又是取当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。这个算法每个

元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为

O(k)。

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//Merge k Sorted Lists : heap sort
struct cmp {
bool operator() (ListNode *a,ListNode *b) {
return a->val > b->val;
}
};
ListNode *mergeKLists(vector<ListNode *> &lists) {
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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: