关于Leetcode的刷题方法,在网上看了很多,每个人都有着不同的见解。作为Leetcode小白,我还是决定用最原始的方法进行刷题,即把每一题的思路都记录下来,虽然比较耗时间,但是个人感觉这样子的方法会让我对题目有更深入的了解。希望能在该专栏中记录下刷题过程中遇到的大大小小的问题🍊。
题目描述
解题思路
- 该题是在合并两个升序链表的基础上的增强版题目,因此我们首先得知道如何合并两个升序链表
合并两个升序链表
- 我们先来回顾一下合并两个有序数组的方法,可以回顾一下之前的博客:Leetcode(4)——寻找两个正序数组的中位数🚄,简而言之,就是通过两个指向数组的指针不断挪动来完成。
- 而链表之于数组的不同之处在于,我们拿到了指向链表某处的一个指针,就能够通过next指针访问该链表剩下的所有元素。
- 而之前合并两个数组的时候当我们指向数组的两个下标指针有一个到达数组末端的时候(不满足
while(idx1 < m && idx2 < n)
),再将另一个数组的剩下的元素一个个复制到新数组中。但是如果是链表的话,我们只需要将另一个链表的当前指针赋予新链表的末尾即可,减少了很多操作。
合并K个升序链表
- 最容易想到的就是用一个空的链表与这K个链表进行 K次的 合并两个链表 的操作,因此用一个for循环不断进行合并即可
- 不过看了题解还有分治法,优先队列法等更好的方法,我就没有深入实现啦。
题目代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode * p = new ListNode(-1); //存放最终结果的链表,作为哑指针
int n = 0;
while (n < lists.size()) {
p->next = mergeTwoLists(lists[n], p->next); //合并第i个链表与最终结果
n ++;
}
return p->next; //返回最终结果
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode*result = new ListNode(-1); //哑指针
ListNode *p = result;
while (l1 && l2) { //两个指针都未到达链表的末尾
if (l1->val < l2->val) { //判断较小的情况
p->next = l1;
p = p->next;
l1 = l1->next;
}
else {
p->next = l2;
p = p->next;
l2 = l2->next;
}
}
if (l1) { //表示链表l1未合并完
p->next = l1;
}
else { //表示链表l2未合并完
p->next = l2;
}
return result->next;
}
};