一、两两交换链表节点
本题在刚开始的时候没有设置虚拟头结点,且只设置了一个缓存变量,因此在nex指针切换的时候给自己绕晕了,一直找不到解法。同时,循环条件也给他想复杂了,原本想的是定义一个计数器,每逢交换两次就切换节点。但其实只要保证cur->next和cur->next->next两个指针不为空即可。
cur的更替也是中间的一个错点。本题设置了虚拟头结点,如果把两个节点看成一组的话,就把cur的位置放在这一组的前面,例如0号 1号节点为一组,那么这组的前面就是虚拟头结点,cur初始位置_dummyhead,更替后,23号为一组,那么cur变成1号节点即cur=cur->next->next。
最后要注意,返回的时候要返回头节点而不是虚拟头结点即返回_dummyhead->next,因为_dummyhead节点要delete掉,所以要提前把有关于_dummyhead的结果保存下来
/**
* 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;
temp->next=temp1;
cur=cur->next->next;
}
ListNode*result=_dummyhead->next;
delete _dummyhead;
return result;
}
};
二、删除链表倒数N个节点
一看到题目,第一想法是先把链表反转,然后再进正向删除。 在看完题解后,双指针的算法让我醍醐灌顶。链表倒数的操作可以让两个指针保持一定差值进行同时移动的操作,来达到取倒数的目的。代码的实现思路跟题解一致。
/**
* 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*_dummyhead=new ListNode(0);
_dummyhead->next=head;
ListNode*fastcur=_dummyhead;
ListNode*lowcur=_dummyhead;
while(n--){
fastcur=fastcur->next;
}
fastcur=fastcur->next;
while(fastcur!=nullptr){
fastcur=fastcur->next;
lowcur=lowcur->next;
}
ListNode*temp=lowcur->next;
lowcur->next=lowcur->next->next;
delete temp;
ListNode*result=_dummyhead->next;
delete _dummyhead;
return result;
}
};
三、链表相交
对于这个题,我起初有点懵,不知道相交的概念是什么,后来想到了是二者开始存在指针相同的节点就是要返回的节点。但是具体操作我又搞不清楚,也想过用哈希表来做,最后想了一个次优解的办法,只能判断有没有交点不能找到交点是什么。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode*curA=headA;
ListNode*curB=headB;
while(curA->next!=nullptr){
curA=curA->next;
}
while(curB->next!=nullptr){
curB=curB->next;
}
if(curA!=curB)return NULL;
else{
}
}
};
题解的思路是,先把二者的起点搞成一致,然后依次遍历寻找相同指针。其中有个细节是,要把长度长的链表放在A位置,这样后续的代码就可以写成一套方案不用再判断哪个长哪个短了。
SWAP(A1.A2);函数可以用来交换指针,可以用来交换值,变量名名称不变,变量的内容改变。
/**
* 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*curA=headA;
ListNode*curB=headB;
int lenA=0;
int lenB=0;
while(curA){
lenA++;
curA=curA->next;
}
while(curB){
lenB++;
curB=curB->next;
}
curA=headA;
curB=headB;
if(lenA<lenB){
swap(lenA,lenB);
swap(curA,curB);
}//到此为止,确立了以A链表为长链表
int charge=lenA-lenB;
while(charge--){
curA=curA->next;
}
while(curA!=nullptr){
if(curA==curB){
return curA;
}
curA=curA->next;
curB=curB->next;
}
return NULL;
}
};
四、 环形链表
?这是啥
定义快慢指针,若有环,说明快指针能与慢指针重合
在有环的基础上,已知快慢指针的重合点是相遇点,根据画图已知:此时令一个新的指针从起点出发,让二者相遇即是环的入口

/**
* 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*fast=head;
ListNode*low=head;
while(fast!=nullptr&&fast->next!=nullptr){
fast=fast->next->next;
low=low->next;
if(low==fast){
ListNode*index1=fast;
ListNode*index2=head;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};
链表终于完了!!!
如果需要增删改 就引入虚拟头结点
368

被折叠的 条评论
为什么被折叠?



