原文链接:http://blog.csdn.net/a83610312/article/details/8554241
题目描述:
有一系列已排好序的链表,将其合并成有序的一张链表;
第一反应是运用胜者树或败者树可以很方便的求解;
因为STL提供了堆操作的函数,所以这里借助堆来求解;
思路是:首先将k个链表的第一个节点集合,建堆,然后取出堆顶的节点,链接到结果链表上,然后将该节点的下一个节点入堆,直到所有链表都已经完成;
下面的Node结构体好像根本无必要,刚开始没注意是链表(而链表可以很方便的获取下一个节点,如果是数组的话还得记录它来自哪个数组);
有亮点需要注意:
1.当一条链表结束的时候,添加值为INF的新Node加入堆,可以方便地避免NULL的判断;
2.make_heap()默认是大顶堆,所以要显示指定使用greater<node>(),来获取小顶堆;
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
- #define LN ListNode*
- #define HEAP heap.begin(),heap.end()
- #define PB push_back
- #define INF 1000000
- struct node
- {
- int val;
- LN from;
- node(ListNode* n)
- {
- if ( n==NULL )
- {
- val=INF;
- }
- else
- {
- val=n->val;
- }
- from=n;
- }
- bool operator<(const node& other)const
- {
- return val<other.val;
- }
- bool operator>(const node& other)const
- {
- return val>other.val;
- }
- };
- class Solution {
- public:
- ListNode *mergeKLists(vector<ListNode *> &lists) {
- // Start typing your C/C++ solution below
- // DO NOT write int main() function
- if (lists.empty()) return NULL;
- int n= lists.size();
- vector<node> heap;
- heap.reserve(n);
- for( int i=0;i<n;i++)
- heap.PB(node(lists[i]));
- make_heap(HEAP,greater<node>());
- LN head= new ListNode(0);
- LN pL = head;
- pop_heap(HEAP,greater<node>());
- node small=heap.back();
- heap.pop_back();
- while(small.val!=INF)
- {
- LN next=small.from->next;
- pL->next=small.from;
- small.from->next=NULL;
- pL=pL->next;
- heap.PB(node(next));
- push_heap(HEAP,greater<node>());
- pop_heap(HEAP,greater<node>());
- small=heap.back();
- heap.pop_back();
- }
- LN ret=head->next;
- delete head;
- return ret; }
- };