链表中的节点每k个一组翻转
合并k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。
示例
输入:[{1,2,3},{4,5,6,7}]
返回值:{1,2,3,4,5,6,7}
方法一 c++ STL
使用STL中的multiset来维护k个值,并且每次只取其中最小的一个存入链表中。当取完最小的那个再将取的那一列的链表弹出最新的值。
代码
ListNode *mergeKLists(vector<ListNode *> &lists) {
multiset<pair<int, int> > arr;
int n = lists.size();
for(int i = 0; i < n; i ++){
if(!lists[i]) continue;
arr.insert({lists[i]->val, i});
lists[i] = lists[i]->next;
}
ListNode* result = new ListNode(0);
ListNode* head = result;
while(arr.size()){ //不断的循环判断数组是否为空
pair<int, int> pp = *arr.begin();
arr.erase(arr.begin());
if(!head){
head = new ListNode(pp.first);
}else{
head->next = new ListNode(pp.first);
head = head->next;
}
if(lists[pp.second]){//如果当前取出的元素还有下一个则将下一个的元素补充到数组中
arr.insert({lists[pp.second]->val, pp.second});
lists[pp.second] = lists[pp.second]->next;
}
}
return result->next;
}时间复杂度 会遍历所有元素n每次会将元素插入set中,所以复杂度为
空间复杂度 multiset中的数据最多只会存入k个
方法二 归并排序
将数组两两进行合并,使用归并的思想
ListNode *mergeKLists(vector<ListNode *> &lists) {
int size = lists.size();
if(size == 0) return nullptr;
if(size == 1) return lists[0];
return mergeList(lists, 0, size - 1);
}
ListNode *mergeList(vector<ListNode *> &lists, int s, int e){
if(s == e) return lists[s];
if(s > e) return nullptr;
auto i = mergeList(lists, s, (s + e) / 2); //向左走
auto j = mergeList(lists, (s + e) / 2 + 1, e); //向右走
return merge(i, j);
}
//归并排序
ListNode *merge(ListNode *a, ListNode *b){ //合并两个
ListNode *result = new ListNode(0);
ListNode *now = result;
while(a && b){
if(a->val < b->val) {
now->next = a;
now = now->next;
a = a->next;
}else{
now->next = b;
now = now->next;
b = b->next;
}
}
if(a) now->next = a;
if(b) now->next = b;
return result->next;
}时间复杂度 归并排序复杂度
空间复杂度 归并排序中合并存储链表最多存储整个链表长度

京公网安备 11010502036488号