题目24. 两两交换链表中的节点 - 力扣(LeetCode)
/**
* 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* swapPairs(ListNode* head) {
ListNode* newhead=new ListNode(0);
newhead->next=head;
ListNode* prev=newhead;
ListNode* cur=head;
if(head==nullptr)//头为空
{
return head;
}
ListNode* next=head->next;//头不为空
while(next!=nullptr)
{
ListNode* nnext=next->next;
next->next=cur;
cur->next=nnext;
prev->next=next;
prev=prev->next->next;
cur=prev->next;
if(cur==nullptr)
{
break;
}
next=cur->next;
}
return newhead->next;
}
};
题目19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
/**
* 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* newhead=new ListNode(0);//虚拟头节点,链表题中要常用
newhead->next=head;
ListNode* slow=newhead;
ListNode* fast=newhead;
//快指针先走n步
while(n-->0)
{
fast=fast->next;
}
//快慢指针同时走
ListNode* prev=slow;
while(fast!=nullptr)
{
prev=slow;
slow=slow->next;
fast=fast->next;
}
//删除指向slow的指针
prev->next=slow->next;
delete slow;
return newhead->next;
}
};
题目面试题 02.07. 链表相交 - 力扣(LeetCode)
/**
* 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) {
//求两个链表长度差值
//移动指向较长链表的指针
//同时移动两个链表指针,比较指针是否相等,链表相交比较的是地址相等,不是值相等
int alen=0;
int blen=0;
ListNode* pa=headA;
ListNode* pb=headB;
while(pa!=nullptr)
{
pa=pa->next;
alen++;
}
while(pb!=nullptr)
{
pb=pb->next;
blen++;
}
int n=0;
pa = headA;
pb = headB;
if(alen>blen)
{
n=alen-blen;
while(pa!=nullptr&&n-->0)
{
pa=pa->next;
}
}else
{
n=blen-alen;
while(pb!=nullptr&&n-->0)
{
pb=pb->next;
}
}
while(pb!=nullptr)
{
if(pb==pa)
{
return pb;
}
pa=pa->next;
pb=pb->next;
}
return nullptr;
}
};
题目142. 环形链表 II - 力扣(LeetCode)
/**
* 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* slow=head;
ListNode* fast=head;
int flag=0;//0有环 1无环
while(fast!=nullptr&&fast->next!=nullptr)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
flag=1;//有环
break;//跳出循环
}
}
if(flag==0)
{
return nullptr;//无环
}
ListNode* newn=head;
ListNode* meet=slow;//相遇点
while(newn!=meet)
{
newn=newn->next;
meet=meet->next;
}
return meet;
}
};
最后
两两交换链表中的节点 24 删除链表的倒数第N个节点 19 链表相交 02.07 环形链表II 142
双指针用法 快慢指针用法
环形链表就是快慢指针判断是否有圈,以及在相遇点和起始点两个指针同步移动,相遇就是环入口
链表相交就是统计链表长度,长链表指针走链表长度之差,然后两个链表指针同步走,要是相等就相交
删除链表倒数第N个节点,快指针先走N步,可以添加虚拟头节点,方便计算倒数第几个节点,然后快慢指针同步走,知道满足条件
两两交换链表中的节点,就是典型的多指针+虚拟头节点应用,要边画图边写最合适。
注意跳出循环的条件,还有注意不要进行空指针访问,多注意