Day 4 | 24. 两两交换链表中的节点、19. 删除链表的倒数第 N 个结点、160. 链表相交、142. 环形链表 II
24. 两两交换链表中的节点
初见:
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *vitual=new ListNode(0);
vitual->next=head;
ListNode *work=vitual;
while(work->next!=nullptr && work->next->next!=nullptr){
ListNode *temp1=work->next;
ListNode *temp2=work->next->next->next;
work->next=work->next->next;
work->next->next=temp1;
work->next->next->next=temp2;
work=work->next->next;
}
return vitual->next;
}
};
19. 删除链表倒数第 N 个结点
初见思路:遍历一遍链表,得到链表的长度,以此确定倒数第N个节点 是 第length-N+1个节点。因此需要找到 前一个节点,也就是第length- N个。(从1–>length-N,即从0–>length-N-1)
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *vitual=new ListNode(0,head);
ListNode *work=vitual;
int length=0;
while(work->next!=0){
work=work->next;
length++;
}
work=vitual;
for(int i=0;i<length-n;i++ ){
work=work->next;
}
work->next=work->next->next;
return vitual->next;
}
};
改良后:使用快慢指针,快指针走N步后,慢指针开始移动。快指针抵达链表最后一个元素时,慢指针恰好指向倒数第N个元素。然而删除节点,需要指针指向前一个节点,因此慢指针要再落后快指针一次再出发,即快指针先走N+1步,慢指针出发。
代码如下:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *vitual=new ListNode(0);
vitual->next=head;
ListNode *slow=vitual;
ListNode *fast=vitual;
while(n--&&fast!=nullptr){
fast=fast->next;
}
fast=fast->next;
while(fast!=nullptr){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return vitual->next;
}
};
160.相交链表
初见思路:若相交,则地址相同,地址相同可得出val相同,
找到val相同的节点再判断next是否相等,若相等,则相交。
由于不一定对齐,想的是双重循环,复杂度为O(n^2),就不贴代码了。
改良后: 看了卡哥的讲解,可以利用链表的长度差,来使他们对齐,而且根本不需要利用val来判断,直接比较指针是否相同即可。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *A=headA;
ListNode *B=headB;
int lenA=0;
int lenB=0;
while(A){
lenA++;
A=A->next;
}
while(B){
lenB++;
B=B->next;
}
A=headA;
B=headB;
if(lenA<lenB){ //让A为长链表
swap(lenA,lenB);
swap(A,B);
}
int gap=lenA-lenB;
while(gap--){
A=A->next;
}
while(A){
if(A==B)
return A;
A=A->next;
B=B->next;
}
return NULL;
}
};