【Leetcode】 Merge k Sorted Lists
Leetcode第23题:
题目的意思就是讲多个有序的链表合并成一个有序的链表。
解题思路:因为所有的链表都是有序的。我们可以将所有链表的首节点拿出来建立一个小根堆。每次取堆顶的节点即最小的节点。取完最小节点后,如果这个最小节点有后续节点,则加到小根堆中,并调整小根堆。再循环上面的操作,取堆顶节点并将下一个节点加到堆中,一直循环直到堆中的元素为空。
下面贴出完成代码(这里为了锻炼自己的代码能力,手动实现了一个小根堆。在标准库里面是有个优先级队列的,其实可以直接用)
#include <iostream>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
//小根堆
class ListNodeHeap
{
public:
ListNodeHeap(size_t cap)
{
m_node_array = new ListNode*[cap];
m_size = 0;
}
~ListNodeHeap()
{
delete[] m_node_array;
}
void Push(ListNode* node)
{
if (!node) return;
m_node_array[m_size] = node;
int cur_index = m_size;
while (cur_index > 0)
{
int parent_index = (cur_index - 1) / 2;
if (m_node_array[parent_index]->val <= m_node_array[cur_index]->val)
break;
std::swap(m_node_array[parent_index], m_node_array[cur_index]);
cur_index = parent_index;
}
m_size++;
}
ListNode* Pop()
{
if (Size() == 0)
return NULL;
m_size--;
ListNode* ret = m_node_array[0];
std::swap(m_node_array[0], m_node_array[m_size]);
int cur_index = 0;
while (2 * cur_index + 1 < m_size)
{
int l_child = 2 * cur_index + 1;
int r_child = 2 * cur_index + 2;
int min_index = l_child;
if (r_child < m_size && m_node_array[r_child]->val < m_node_array[l_child]->val)
min_index = r_child;
if (m_node_array[cur_index]->val <= m_node_array[min_index]->val)
break;
std::swap(m_node_array[min_index], m_node_array[cur_index]);
cur_index = min_index;
}
return ret;
}
size_t Size()
{
return m_size;
}
private:
size_t m_size;
ListNode** m_node_array;
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNodeHeap node_heap(lists.size());
ListNode* head = NULL;
ListNode* cur = NULL;
for (auto it : lists)
{
if (!it) continue;
node_heap.Push(it);
}
while (node_heap.Size() > 0)
{
ListNode* tmp = node_heap.Pop();
if (!tmp)
break;
if (!cur)
{
cur = tmp;
head = cur;
}
else
{
cur->next = tmp;
cur = tmp;
}
if (cur->next)
{
node_heap.Push(cur->next);
cur->next = NULL;
}
}
return head;
}
};
//下面是测试的相关代码
void PrintList(ListNode* list_node)
{
while (list_node)
{
if (list_node->next)
std::cout << list_node->val << "->";
else
std::cout << list_node->val << std::endl;
list_node = list_node->next;
}
}
ListNode* CreateNodeList(int* a, int n)
{
ListNode* head = NULL;
ListNode* cur = NULL;
for (int i = 0; i < n; i++)
{
ListNode* node = new ListNode(a[i]);
if (!cur)
{
cur = node;
head = cur;
}
else
{
cur->next = node;
cur = node;
}
}
return head;
}
int main()
{
Solution s;
int a1[] = { 1, 4, 5 };
int a2[] = { 1, 3, 4 };
int a3[] = { 2, 6 };
std::vector<ListNode*> vec;
vec.push_back(CreateNodeList(a1, 3));
vec.push_back(CreateNodeList(a2, 3));
vec.push_back(CreateNodeList(a3, 2));
ListNode* ret = s.mergeKLists(vec);
PrintList(ret);
}
最终在leetcode上提交给出很好的结果: