两两交换
思路
和翻转链表的其实差不多,找到要交换的两个节点的前一位,然后
while(first!=NULL&&first->next!=NULL){
ListNode* temp=first->next;
cur->next=temp;
first->next=temp->next;
temp->next=first;
cur=cur->next->next;
first=first->next;
}
犯过的错误
设置虚拟头结点时直接=head,应该dummyhead->next=head
ListNode* dummyhead=head;
ListNode* cur =dummyhead;
ListNode* first=head;
删除链表的倒数第N个节点
思路
代码实现
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead=new ListNode();
dummyhead->next=head;
ListNode*fast=dummyhead;
ListNode*slow=dummyhead;
int i=0;
while(fast->next!=nullptr){
if(i==n){
slow=slow->next;
}
else
i++;
fast=fast->next;
}
ListNode* temp=slow->next;
slow->next=temp->next;
delete temp;
return dummyhead->next;
}
};
链表相交也是同样的思路,先分别获得长度m与n,
如果m短n长,那只用比较n的后m位,所以要先用一个指针来移动,
两者在同一位置后再一 一判断。
环形链表
环形链表
用了一个一次移动两个位置的快指针和一个正常移动的慢指针来判断是否是环形,如果不是环形两者不可能相交。
慢指针(x+y)*2=x+y+(z+y)*n,n必然>=1
x=(n-1)(z+y)+z
n=1时,说明x=z
让相遇点index2和头结点处的index1同时出发,则在入口处相遇。
n>1时,则转了n-1圈再走z后会和index1处在入口相遇。
代码
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow=head;
ListNode* fast=head;
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
ListNode* index1=head;
ListNode* index2=slow;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};