DAY4 链表part02
今日任务
● 24. 两两交换链表中的节点
● 19.删除链表的倒数第N个节点
● 面试题 02.07. 链表相交
● 142.环形链表II
● 总结 //有一定难度,需要好好琢磨
24. 两两交换链表中的节点
用虚拟头结点,这样会方便很多。
题目链接/文章讲解/视频讲解: https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html
*注意画图理清思路
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* swapPairs(ListNode* head) { 14 ListNode* dummy=new ListNode(0); 15 dummy->next=head; 16 ListNode* p=dummy; 17 ListNode* q=dummy->next; 18 19 while(q!=NULL&&q->next!=NULL) 20 { 21 ListNode* tmp=q->next; 22 q->next=tmp->next; 23 tmp->next=q; 24 p->next=tmp; 25 26 p=p->next->next;//p走两格 27 q=q->next; 28 } 29 head=dummy->next; 30 return head; 31 } 32 };
19.删除链表的倒数第N个节点
双指针的操作,要注意,删除第N个节点,那么我们当前遍历的指针一定要指向 第N个节点的前一个节点
*双指针的经典用法:让fast先走N,再让fast和slow同时走,直到fast到尾结点,此时slow指向目标节点的前一位置,即倒数N+1结点;
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* removeNthFromEnd(ListNode* head, int n) { 14 ListNode* dummy=new ListNode(0); 15 dummy->next=head; 16 ListNode* fast=dummy; 17 ListNode* slow=dummy; 18 for(int i=0;i<n;i++) fast=fast->next; 19 20 while(fast->next!=NULL)//注意此条件 21 { 22 fast=fast->next; 23 slow=slow->next; 24 }//出循环时fast指向最后一个节点,slow指向目标节点前一个结点 25 ListNode* tmp=slow->next; 26 slow->next=tmp->next; 27 delete(tmp); 28 //以上三行可写作 slow->next=slow->next->next; 29 30 head=dummy->next; 31 return head; 32 } 33 };
面试题 02.07. 链表相交
方法一:让A和B“对齐”,从而同步移动指针,可以找到公共首节点;
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 //对齐 10 class Solution { 11 public: 12 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 13 int lenA=0; 14 int lenB=0; 15 ListNode* cura=headA; 16 ListNode* curb=headB; 17 while(cura!=NULL) 18 { 19 lenA++; 20 cura=cura->next; 21 } 22 while(curb!=NULL) 23 { 24 lenB++; 25 curb=curb->next; 26 } 27 cura=headA; 28 curb=headB; 29 if(lenA>lenB) 30 { 31 int cnt=lenA-lenB; 32 while(cnt--) cura=cura->next; 33 } 34 else if(lenA<lenB) 35 { 36 int cnt=lenB-lenA; 37 while(cnt--) curb=curb->next; 38 }//分类讨论 39 while(cura!=NULL&curb!=NULL) 40 { 41 if(cura==curb) return cura; 42 else 43 { 44 cura=cura->next; 45 curb=curb->next; 46 } 47 } 48 return cura; 49 } 50 };
方法二:合并链表实现同步移动(画图)
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 //合并链表实现同步移动 10 class Solution { 11 public: 12 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 13 ListNode* curA=headA; 14 ListNode* curB=headB; 15 while(curA!=curB) 16 { 17 if( curA==NULL) curA=headB; 18 else curA=curA->next; 19 20 if(curB==NULL) curB=headA; 21 else curB=curB->next; 22 } 23 return curA; 24 }//理解 25 };
142.环形链表II
题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html
*明确任务:判断有无环和找到入环的第一结点
*思想:双指针判断有无环(fast=fast->next->next,slow=slow->next),经证明,若fast和slow相遇,则一定有环且在环内相遇;
数学证明,若meet从相遇结点出发,index从head出发,则二者会在环的首节点相遇(相同速度);
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *detectCycle(ListNode *head) { 12 ListNode *fast=head; 13 ListNode *slow=head; 14 15 while(fast!=NULL&&fast->next!=NULL)//判断有没有环 16 { 17 slow=slow->next; 18 fast=fast->next->next; 19 if(fast==slow)//有环 20 { 21 ListNode* meet=slow;//相遇节点 22 ListNode* index=head;//首节点 23 24 while(meet!=index) 25 { 26 meet=meet->next; 27 index=index->next; 28 }相遇则找到环的入口 29 return meet; 30 } 31 } 32 33 return NULL;//没找到 34 } 35 };