赞
踩
给定k个升序排列的链表,将其合并为一个升序链表并返回头节点。
Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6
类似于 leetcode21 合并两个升序链表。 仍然是比较各个链表头节点的值,将值最小的节点放在合并后的链表后面。
为了更快的找到k个头节点中值最小的那个节点,可以使用小根堆来保存k个头节点,每次取出堆顶元素插入合并后的链表中,然后将下一个节点加入堆中。
由于使用堆维护链表最小值的节点,堆的插入是O(logk)的,所以总的时间复杂度是O(nlogk)。
使用了堆所以空间复杂度为O(n)
class Solution { public: struct cmp{ bool operator()(ListNode* l1, ListNode* l2){ return l1->val > l2->val; } }; ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*,vector<ListNode*>,cmp> heap; auto dummy = new ListNode(-1), tail = dummy; for(auto l:lists){ if(l) heap.push(l); } while(heap.size()){ auto p = heap.top(); heap.pop(); tail = tail->next = p; if(p->next) heap.push(p->next); } return dummy->next; } };
其中,实现小根堆的方法是重载 < 号。
给定两个升序链表,要求合并这两个链表并返回合并后链表的头节点。
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
使用两个链表的头节点,比较两个节点值的大小,将值小的先插入合并后的链表中,由于链表的头节点会被改变,所以使用虚拟头节点简化代码。
O(n)
O(1)
class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { auto dummy = new ListNode(-1), tail = dummy; while(l1 && l2){ if(l1->val <= l2->val){ tail = tail->next = l1; l1 = l1->next; } else{ tail = tail->next = l2; l2 = l2->next; } } if(l1) tail->next = l1; if(l2) tail->next = l2; return dummy->next; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。