两两交换链表中的节点
/**
* 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* dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode* cur=dummyHead;
while(cur->next!=nullptr&&cur->next->next!=nullptr){
ListNode* temp=cur->next;
ListNode* temp1=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=temp;
cur->next->next->next=temp1;
cur=cur->next->next;
}
return dummyHead->next;
}
};
删除链表的倒数第N个节点
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) {
if(!head) return nullptr;
ListNode *Head=new ListNode(0);
Head->next=head;//先创建第一个节点,next连接链表的头节点,这样当删除第一个节点的时候,就会得到了Head->next的节点,即得到第二个节点,否则得不到下一个节点
ListNode* L=head;
ListNode* R=head;
for(int i=0;i<n;i++) L=L->next;//定义两节点;将L的节点向后移动n位;当L到达末尾指针,R刚好到需要删除的第n个节点
ListNode* pre=Head;
while(L)
{
L=L->next;
pre=R;
R=R->next;
}
pre->next=R->next;
return Head->next;
}
};
### 链表相交
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA=headA,* curB=headB;
int m=0,n=0;
while(curA){
curA=curA->next;
m++;
}
while(curB){
curB=curB->next;
n++;
}
curA=headA;
curB=headB;
if(m<n){
swap(m,n);
swap(curA,curB);
}
int gap=m-n;
while(gap--){
curA=curA->next;
}
while(curA!=NULL){
if(curA==curB){
return curA;
}
curA=curA->next;
curB=curB->next;
}
return NULL;
}
};
环形链表
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next->next;
slow=slow->next;
if(slow==fast){
ListNode* index1=slow;
ListNode* index2=head;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};
可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
为什么fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇呢,而不是永远的错开呢
首先第一点:fast指针一定先进入环中,如果fast指针和slow指针相遇的话,一定是在环中相遇,这是毋庸置疑的。
fast和slow各自再走一步, fast和slow就相遇了
这是因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
此时已经可以判断链表是否有环了,那么接下来要找这个环的入口了。
从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。