/*解题思路:
* 由于每条链表是非递减排列,每次取所有链表的头节点中值最小的节点插入到合并后链表的结尾,因此可以
* 利用小根堆的特性,建立 <值, 节点指针> 的映射,对于每条链表将其头结点插入小根堆,每次取堆顶元素
* top 插入到新链表即可,如果所取节点 top->next 非空,则应将 top->next 的键值对压入堆。
*/
算法实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
typedef pair<int, ListNode*> Entry;
struct comp {
/* 定义堆的比较规则 */
bool operator()(const Entry& a, const Entry& b) {
return b.first < a.first;
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<Entry, vector<Entry>, comp> pq;
for (ListNode* p : lists) {
if (p)
pq.push({p->val, p});
}
if (pq.empty())
return nullptr;
Entry top = pq.top(); pq.pop(); //弹出第一个最小节点,作为头结点
ListNode* head = top.second; //得到链表头指针
if (head->next != nullptr) //如果这条链表不止一个节点,则将第二个节点压入堆
pq.push({head->next->val, head->next});
ListNode* tail = head; //tail作为尾节点指针
while (!pq.empty()) {
top = pq.top(); pq.pop(); //弹出当前最小节点,并接入链表结尾
tail->next = top.second; tail = tail->next;
if (top.second->next != nullptr)
pq.push({top.second->next->val, top.second->next});
}
tail->next = nullptr;
return head;
}
};