本题用普通方法比较简单
注意如果一个ListNode*为NULL,应及时删除,否则会TLE
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode * dummy = new ListNode(0);
ListNode * cur = dummy;
while (true)
{
int min = INT_MAX;
int index = -1;
for (int i = lists.size() - 1; i >= 0; i--)
{
if (lists[i] != NULL && lists[i]->val < min)
{
min = lists[i]->val;
index = i;
}
}
if (index == -1) break;
cur->next = new ListNode(min);
cur = cur->next;
lists[index] = lists[index]->next;
if (lists[index] == NULL)
lists.erase(lists.begin() + index);
}
ListNode * head = dummy->next;
delete dummy;
return head;
}
第二种方法用到最小堆,使用make_heap, push_heap, pop_heap
class Solution {
struct MyGreater
{
bool operator() (pair<ListNode*, int>& l, pair<ListNode*, int>& r)
{
return l.first->val > r.first->val;
}
};
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
vector<pair<ListNode*, int>> heap;
int heapSize = lists.size();
for (int i = heapSize - 1; i >= 0; i--)
{
if (lists[i] == NULL)
{
heapSize--;
continue;
}
heap.push_back(make_pair(lists[i], i));
lists[i] = lists[i]->next;
}
if (heapSize <= 0) return NULL;
make_heap(heap.begin(), heap.begin() + heapSize, MyGreater());
ListNode * root = new ListNode(0);
ListNode * cur = root;
while (true)
{
pop_heap(heap.begin(), heap.begin() + heapSize, MyGreater());
cur->val = heap[heapSize - 1].first->val;
int heapNum = heap[heapSize - 1].second;
if (lists[heapNum] != NULL)
{
heap[heapSize - 1].first->val = lists[heapNum]->val;
lists[heapNum] = lists[heapNum]->next;
push_heap(heap.begin(), heap.begin() + heapSize, MyGreater());
}
else
{
heapSize--;
if (heapSize == 0)
{
return root;
}
}
cur->next = new ListNode(0);
cur = cur->next;
}
return NULL;
}
};
pop_heap其实并不是将堆顶删除,而是将堆顶放在了vector中size()-1的位置,并排序0-size()-2。
push_heap是假设0-size()-2已经是一个堆了,将vector末尾元素插入到堆中。
我写的时候使用heapSize记录当前堆的大小,并且使用pair<ListNode*, int>记录某个元素对应在lists中的位置