新增虚拟节点,思路如下:
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){//只要后面2个结点不为空,就进行交换
ListNode* tmp=cur->next;
ListNode* tmp1=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=tmp;
cur->next->next->next=tmp1;
cur=cur->next->next;
}
ListNode* result=dummyHead->next;
delete dummyHead;
return result;
}
};
关键思想:头结点前设置一个虚拟结点,利用双指针(fast,slow)定位倒数第N个结点——一个指针先移动N+1位,之后两指针同步后移,直到偏后面的指针指向表尾;
注意事项:fast与slow偏移N+1位,方便定位倒数第N个的前驱,方便删除
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead=new ListNode(0);
dummyHead->next=head;
ListNode* fast=dummyHead;
ListNode* slow=dummyHead;
while(n-- &&fast!=nullptr){
fast=fast->next;
}
fast=fast->next;//偏移N+1位,方便定位删除节点的前驱
while(fast!=nullptr){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;//ListNode* tmp=slow->next;
//slow->next=tmp->next;
//delete tmp;
return dummyHead->next;
}
};
思路:
将两个链表末尾对齐,
各新增定位指针从较短链表的头结点所在位置开始,
逐一进行比较对应节点的数值大小,直到相等或末尾停止。
预处理:
计算各链表的长度;
将较长的链表设为A,方便比较;
确定各个链表指针的初始定位;
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* Acur=headA;
ListNode* Bcur=headB;
int alen=0,blen=0;
while(Acur!=NULL){
alen++;
Acur=Acur->next;
}
while(Bcur!=NULL){
blen++;
Bcur=Bcur->next;
}
Acur=headA;
Bcur=headB;
if(alen<blen){
swap(alen,blen);
swap(Acur,Bcur);
}
int gap=alen-blen;
while(gap--){
Acur=Acur->next;
}
while(Acur!=NULL){
if(Acur==Bcur)
return Acur;
Acur=Acur->next;
Bcur=Bcur->next;
}
return NULL;
}
};
思想:
快慢指针思想,设置两个指针,从头结点开始,一个每次走一步,一个每次走两步。
判断是否有环:如果有环,那么必定会相遇;
判断相遇位置:
fast指针走过的节点数 = slow指针走过的节点数 * 2:
(x + y) * 2 = x + y + n (y + z)
x = (n - 1) (y + z) + z
从头结点出发一个指针,从相遇节点也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。
让index1和index2同时移动,每次移动一个节点, 相遇的地方就是环形入口的节点。
注意事项:
n如果大于1就是fast指针在环形转n圈之后才遇到 slow指针。
这种情况和n为1的时候效果一样,只是index1指针在环里多转了(n-1)圈,然后再遇到index2,相遇点依然是环形的入口节点。
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(fast==slow){
ListNode* index1=fast;
ListNode* index2=head;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index2;
}
}
return NULL;
}
};