算法模型总结:链表中的前后指针法
文章目录
本文将持续更新
模型一:交换链表元素
206. 反转链表
1.思路
链表中的前后指针法,通常是为了记录当前元素的前一个元素的,因为单链表是没法去寻找前面的元素的。这样也可以在只遍历一次链表的情况下解决问题。
思路很简单,只要理清楚各个链表元素的链接顺序即可,即如何交换才能让我们拿到所有需要的元素。
2.实现
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur=head;
ListNode* prev=nullptr;
while(cur)
{
ListNode* next=cur->next;
cur->next=prev;
prev=cur;
cur=next;
}
return prev;
}
};
24. 两两交换链表中的节点
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead=new ListNode();
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur->next!=nullptr&&cur->next->next!=nullptr)
{
ListNode* next=cur->next;
ListNode* nnext=next->next;
ListNode* nnnext=nnext->next;
cur->next=nnext;
nnext->next=next;
next->next=nnnext;
cur=next;
}
return dummyhead->next;
}
};
模型二:找规定位置
19. 删除链表的倒数第 N 个结点
1.思路
这一类题的前后指针,往往先让快指针向前前进,然后快慢指针一起前进,最终慢指针的位置就是我们需要的位置。
关键在于在题干中分析出来快指针到底走多远,慢指针才开始走。
2.实现
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead=new ListNode();
dummyhead->next=head;
ListNode* fast=dummyhead;
ListNode* slow=dummyhead;
int count=0;
while(count<=n)
{
fast=fast->next;
count++;
}
while(fast!=nullptr)
{
fast=fast->next;
slow=slow->next;
}
ListNode* next=slow->next;
slow->next=next->next;
delete next;
return dummyhead->next;
}
};
模型三:环形链表
142. 环形链表 II
1.思路
只需要记住三点,找到两个位置,题就可以解了。
- 快指针每次比慢指针多走1步
- 快指针会和慢指针在环中的某一个位置相遇
- 从相遇位置和起始位置以相同的速度同时出发,最终会在环的入口处相遇
2.实现
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast&&fast->next&&slow)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
break;
}
}
if(fast==nullptr||fast->next==nullptr)
{
return nullptr;
}
ListNode* res=head;
while(res!=slow)
{
res=res->next;
slow=slow->next;
}
return res;
}
};
总结
链表中的前后指针法和数组中的前后指针法处理的问题是不同的,注意区分。

浙公网安备 33010602011771号