合并有序链表
直接创建新list,从头开始比较后添加listnode并遍历,最后直到遍历到nullptr说明一个list已经遍历完,添加剩下哪个
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
// 虚拟头结点
ListNode dummy(-1), *p = &dummy;
ListNode *p1 = l1, *p2 = l2;
while (p1 != nullptr && p2 != nullptr) {
// 比较 p1 和 p2 两个指针
// 将值较小的的节点接到 p 指针
if (p1->val > p2->val) {
p->next = p2;
p2 = p2->next;
} else {
p->next = p1;
p1 = p1->next;
}
// p 指针不断前进
p = p->next;
}
if (p1 != nullptr) {
p->next = p1;
}
if (p2 != nullptr) {
p->next = p2;
}
return dummy.next;
}
};
分解有序
分别用指针来生成两部分链表:
ListNode* dummy1 = new ListNode(-1);
// 存放大于等于 x 的链表的虚拟头结点
ListNode* dummy2 = new ListNode(-1);
// p1, p2 指针负责生成结果链表
ListNode* p1 = dummy1, *p2 = dummy2;
ListNode* p = head;
同样也是遍历比较后用指针添加到链表,最后对于原链表不能直接让p前进,而是要断开:
ListNode* temp = p->next;
p->next = nullptr;
p = temp;
最后链接两个链表。
合并k个链表
我们可以想到一种最朴素的方法:用一个变量 ans 来维护以及合并的链表,第 i 次循环把第 i 个链表和 ans 合并,答案保存到 ans 中。
class Solution {
public:
ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
if ((!a) || (!b)) return a ? a : b;
ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
while (aPtr && bPtr) {
if (aPtr->val < bPtr->val) {
tail->next = aPtr; aPtr = aPtr->next;
} else {
tail->next = bPtr; bPtr = bPtr->next;
}
tail = tail->next;
}
tail->next = (aPtr ? aPtr : bPtr);
return head.next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *ans = nullptr;
for (size_t i = 0; i < lists.size(); ++i) {
ans = mergeTwoLists(ans, lists[i]);
}
return ans;
}
};
也可以用优先级队列小顶堆,,不断获取最小节点接到结果链表,并用p推进
判断链表中点和是否包环
直接用快慢指针
浙公网安备 33010602011771号