题目
给定k个有序链表, 将这些链表合并为一个新链表.
Input: [1->4->5, 1->3->4, 2->6]
Output: [1->1->2->3->4->4->5->6]
基础方法
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* vecToListNodes(vector<int> vec) {
if (vec.size() == 0){
return NULL;
}
vector<int>::iterator iter = vec.begin();
ListNode *header = new ListNode(*iter);
ListNode *temp = header;
iter++;
while(iter != vec.end()) {
cout << *iter << endl;
ListNode *node = new ListNode(*iter);
temp->next = node;
temp = node;
iter++;
}
return header;
}
思路1
将k个链表的数都取出来, 放到一个数组, 对数组进行排序, 将数组转化为一个链表.
时间复杂度O(NlogN)(N表示所有节点总量)
空间复杂度O(N)
ListNode* mergeKLists(vector<ListNode*>& lists) {
vector<int> vec;
for(int i = 0;i < lists.size();i++) {
ListNode *tmp = lists[i];
while (tmp != NULL){
vec.push_back(tmp->val);
tmp = tmp->next;
}
}
sort(vec.begin(),vec.end());
return vecToListNodes(vec);
}
思路2
每次找到k个链表中最小的数, 加入到新链表中. 但是时间效率太低, 空间效率也不高.
时间复杂度O(kN)
空间复杂度O(n)
ListNode* mergeKLists(vector<ListNode*>& lists) {
vector<ListNode*> temp = lists;
ListNode *header = NULL;
ListNode *res = NULL;
while(true) {
int min = INT_MAX;
int minIndex = 0;
bool isEnd = true;
for(int i = 0;i < temp.size();i++) {
if (temp[i] != NULL) {
isEnd = false;
}else {
continue;
}
if (min > temp[i]->val) {
min = temp[i]->val;
minIndex = i;
}
}
if (isEnd) {
break;
}
temp[minIndex] = temp[minIndex]->next;
ListNode *node = new ListNode(min);
if (res == NULL) {
header = node;
res = node;
} else {
res->next = node;
res = res->next;
}
}
return header;
}
思路3
采用二分法, 两两合并.
时间复杂度O(Nlogk)
空间复杂度O(1)
ListNode* merge2Lists(ListNode *list1, ListNode *list2) {
ListNode *tmp = new ListNode(0);
ListNode *header = tmp;
while (list1 != NULL && list2 != NULL) {
if (list1-> val < list2->val) {
tmp->next = list1;
list1 = list1->next;
} else {
tmp->next = list2;
list2 = list2->next;
}
tmp = tmp->next;
}
if (list1 != NULL){
tmp->next = list1;
}
if (list2 != NULL) {
tmp->next = list2;
}
return header->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0) {
return NULL;
}
vector<ListNode*> temp = lists;
ListNode *header = NULL;
ListNode *res = NULL;
while (temp.size() > 1)
{
vector<ListNode*> tmp;
for(int i = 0;i < temp.size();) {
ListNode *newListNode;
if (i + 1 < temp.size()) {
newListNode = merge2Lists(temp[i], temp[i+1]);
i += 2;
} else {
newListNode = temp[i];
i += 1;
}
tmp.push_back(newListNode);
}
temp = tmp;
}
return temp.front();
}
总结
二分法两两合并是效率最高的, 复杂问题往往需要拆分为简单问题.