您的位置:首页 > 其它

[leetcode] 23.Merge k Sorted Lists

2015-08-29 17:22 253 查看
题目:

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

题意:

合并k个有序的链表。

我们可以使用红黑树,将k个链表的每个元素都加入,然后每次取出一个最小的元素,然后查看取出的是哪个链表中的元素,就将这个链表中的元素再加入一个。C++中就是用STL的set即可。

代码如下:

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
struct ListNodeWithNo {
int no;
ListNode* node;
ListNodeWithNo(int n, ListNode* list) :no(n), node(list){}
};

struct myCompareList {
bool operator() (const ListNodeWithNo& node1, const ListNodeWithNo& node2) {
return node1.node->val < node2.node->val;
}
};

class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
multiset<ListNodeWithNo, myCompareList> heap;
int size = lists.size();
for (int i = 0; i < size; i++) {
if (lists[i] != NULL) {
heap.insert(ListNodeWithNo(i, lists[i]));
lists[i] = lists[i]->next;
}
}
ListNode* result = new ListNode(0), *curr = result;
while (!heap.empty()) {
curr->next = heap.begin()->node;
int no = heap.begin()->no;
curr = curr->next;
heap.erase(heap.begin());
if (lists[no] != NULL) {
heap.insert(ListNodeWithNo(no, lists[no]));
lists[no] = lists[no]->next;
}
}
curr->next = NULL;
curr = result->next;
delete result;
return curr;
}
};


我们还可以使用堆来完成,STL中使用优先级队列priority_queue即可。

代码如下:

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
struct ListNodeWithNo {
int no;
ListNode* node;
ListNodeWithNo(int n, ListNode* list) :no(n), node(list){}
};

struct myCompareList {
bool operator() (const ListNodeWithNo& node1, const ListNodeWithNo& node2) {
return node1.node->val > node2.node->val;
}
};

class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNodeWithNo, vector<ListNodeWithNo>, myCompareList> heap;
int size = lists.size();
for (int i = 0; i < size; i++) {
if (lists[i] != NULL) {
heap.push(ListNodeWithNo(i, lists[i]));
lists[i] = lists[i]->next;
}
}
ListNode* result = new ListNode(0), *curr = result;
while (!heap.empty()) {
curr->next = heap.top().node;
curr = curr->next;
int no = heap.top().no;
heap.pop();
if (lists[no] != NULL) {
heap.push(ListNodeWithNo(no, lists[no]));
lists[no] = lists[no]->next;
}
}
curr->next = NULL;
curr = result->next;
delete result;
return curr;
}
};


我们还可以使用败者树来完成。

/**
* 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 size = lists.size();
if (size == 0)return NULL;
int *key = new int[size + 1];
key[size] = INT_MIN;

int *loser = new int[size];
for (int i = 0; i < size; i++){
loser[i] = size;
if (lists[i] != NULL)
key[i] = lists[i]->val;
else key[i] = INT_MAX;
}
for (int i = 0; i < size; i++){
adjust(loser, key, i, size);
}

ListNode *head = new ListNode(0), *curr = head;
int min_index = loser[0];
while (key[min_index] != INT_MAX){
curr->next = lists[min_index];
curr = curr->next;
lists[min_index] = lists[min_index]->next;
if(lists[min_index] != NULL) {
key[min_index] = lists[min_index]->val;
}
else key[min_index] = INT_MAX;
adjust(loser, key, loser[0], size);
min_index = loser[0];
}
curr->next = NULL;
curr = head->next;
delete head;
return curr;
}
void adjust(int loser[], int key[], int k, int size){
for (int i = (size + k)/2; i > 0; i /= 2){
if (key[loser[i]] < key[k]){
swap(k, loser[i]);
}
}
loser[0] = k;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: