【LBLD】双指针技巧秒杀七道链表题目
【LBLD】双指针技巧秒杀七道链表题目
原文地址:双指针技巧秒杀七道链表题目
合并两个有序链表
/**
* 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* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode *dummy = new ListNode(-1), *p = dummy;
ListNode *p1 = list1, *p2 = list2;
while(p1 != nullptr && p2 != nullptr) {
if(p1->val < p2->val) {
p->next = p1;
p1 = p1->next;
}
else {
p->next = p2;
p2 = p2->next;
}
p = p->next;
}
if(p1 != nullptr) {
p->next = p1;
}
if(p2 != nullptr) {
p->next = p2;
}
return dummy->next;
}
};
踩坑记录:
- C++声明两个指针:
ListNode *a, *b;
单链表的分解
/**
* 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* partition(ListNode* head, int x) {
ListNode *p = head;
ListNode *dummy1 = new ListNode(-1), *dummy2 = new ListNode(-1);
ListNode *p1 = dummy1, *p2 = dummy2;
while (p != nullptr) {
if (p->val < x) {
p1->next = p;
p1 = p1->next;
}
else {
p2->next = p;
p2 = p2->next;
}
p = p->next;
}
p2->next = nullptr;
p1->next = dummy2->next;
return dummy1->next;
}
};
踩坑记录:
- 一开始遇到了
heap-use-after-free
的报错,使用return 0
检查出错位置,最后发现是没有加上p2-next = nullptr
导致链表存在环,力扣在输出存在环的链表时出现了heap-use-after-free
问题。
合并 k 个有序链表
/**
* 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 *dummy = new ListNode(-1);
ListNode *p = dummy;
// priority_queue
priority_queue<ListNode*, vector<ListNode*>, function<bool(ListNode*, ListNode*)>> pq([](ListNode* a, ListNode* b) {return a->val > b->val;});
for (auto head : lists) {
if(head != nullptr) {
pq.push(head);
}
}
while (!pq.empty()) {
p->next = pq.top();
pq.pop();
if(p->next->next != nullptr) {
pq.push(p->next->next);
}
p = p->next;
}
return dummy->next;
}
};
priority_queue
是优先级队列,这里实现了一个最小堆。
单链表的倒数第 k 个节点
/**
* 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* removeNthFromEnd(ListNode* head, int n) {
ListNode *dummy = new ListNode(-1, head);
ListNode *p1 = dummy;
for (int i = 0; i < n+1; i++) {
p1 = p1->next;
}
ListNode *p2 = dummy;
while (nullptr != p1) {
p1 = p1->next;
p2 = p2->next;
}
p2->next = p2->next->next;
return dummy->next;
}
};
单链表的中点
/**
* 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* middleNode(ListNode* head) {
ListNode *p1 = head, *p2 = head;
while (nullptr != p2 && nullptr != p2->next) {
p1 = p1->next;
p2 = p2->next->next;
}
return p1;
}
};
判断链表是否包含环
只判断
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *p1 = head, *p2 = head;
bool flag = false;
while (nullptr != p2 && nullptr != p2->next) {
p1 = p1->next;
p2 = p2->next->next;
if(flag && p1 == p2) return true;
flag = true;
}
return false;
}
};
寻找环的起点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *p1 = head, *p2 = head;
bool flag = false;
while (nullptr != p2 && nullptr != p2->next) {
p1 = p1->next;
p2 = p2->next->next;
if (p1 == p2 && flag) {
p2 = head;
while(p2 != p1) {
p2 = p2->next;
p1 = p1->next;
}
return p1;
};
if (!flag) flag = true;
}
return nullptr;
}
};
两个链表是否相交
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p1 = headA;
ListNode *p2 = headB;
while (p1 != p2) {
if(p1 == nullptr) p1 = headB;
else if(p2 == nullptr) p2 = headA;
else {
p1 = p1->next;
p2 = p2->next;
}
}
return p1;
}
};