相关链接
视频讲解:帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
视频讲解:链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点_哔哩哔哩_bilibili
面试题 02.07. 链表相交 - 力扣(LeetCode)
暂无视频讲解
视频讲解:把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili
两两交换链表中的节点
解题思路
定义一个虚拟头结点便于统一操作,这道题一定要画图便于直观理解,否则很容易思路混乱。
遇到的难题&总结
1)自己重新模拟过程的时候,指针的指向混乱,还是需要画图。
2)临时结点的作用是便于之前指针的定位。
3)循环终止条件的判断。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* vhead=new ListNode(0);
vhead->next=head;
ListNode* cur=vhead;
while(cur->next!=NULL&&cur->next->next!=NULL)
{
ListNode* tmp1=cur->next;
ListNode* tmp2=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=tmp1;
tmp1->next=tmp2;
cur=cur->next->next;
}
return vhead->next;
}
};
删除链表的倒数第N个结点
解题思路(独立写的版本,1.0版本,代码较为啰嗦)
首先遍历链表求出总数,删除倒数第N个结点其实就是删除第(总数-N)个结点,接着删除结点就是链表的基础操作。
AC代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int size=0;
ListNode* vhead=new ListNode(0);
vhead->next=head;
ListNode* cur=vhead;
ListNode* tmp=cur->next;
while(cur->next!=NULL)
{
size++;
cur=cur->next;
}
int k=size-n;
cur=vhead;
while(k--)
{
cur=cur->next;
tmp=cur->next;
}
ListNode* de=cur->next;
cur->next=tmp->next;
delete de;
return vhead->next;
}
};
双指针解法的解题思路
如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。这里定义虚拟头节点便于操作,我们让fast先移动n+1步,这样慢指针指向的就是要删除的结点的前一个结点,之后便于进行删除操作。
AC代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* vhead=new ListNode(0);
vhead->next=head;
ListNode* fast=vhead;
ListNode* slow=vhead;
n=n+1;
while(n--&&fast!=NULL)
{
fast=fast->next;
}
while(fast!=NULL)
{
fast=fast->next;
slow=slow->next;
}
ListNode *tmp = slow->next;
slow->next = tmp->next;
delete tmp;
return vhead->next;
}
};
遇到的困难&总结
1)代码在执行过程中报错,虚拟头结点需要与原链表进行相连!!!
2)不懂的时候多画图
链表相交
解题思路
就是求两个链表交点节点的指针。 交点不是数值相等,而是指针相等。分别计算出两个链表的长度,求出两个链表长度的差值,然后让h1移动使得两个链表的末尾对齐,接着就可以比较h1和h2是否相同,如果不相同,同时向后移动h1和h2,如果遇到h1== h2,则找到交点,否则循环退出返回空指针。
AC代码
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* h1=headA;
ListNode* h2=headB;
int lenA=0,lenB=0;
while(h1!=NULL)
{
lenA++;
h1=h1->next;
}
while(h2!=NULL)
{
lenB++;
h2=h2->next;
}
h1=headA;
h2=headB;
if(lenB>lenA)
{
swap(lenA,lenB);
swap(h1,h2);
}
int gap=lenA-lenB;
while(gap--)
{
h1=h1->next;
}
while(h1!=NULL)
{
if(h1==h2)
return h1;
h1=h1->next;
h2=h2->next;
}
return NULL;
}
};
遇到的困难
1)起初不理解链表相交的含义,以为是数值相等。
2)计算链表长度的时候,循环终止条件判断错误,误以为是h1->next!=NULL(这么低级的错误,我晕)
3)swap函数理解不够透彻
环形链表
AC代码
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(slow==fast)
{
ListNode* index1=fast;
ListNode* index2=head;
while(index1!=index2)
{
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};
总结
最重要的就是判断是否有环以及环的入口,视频真的讲解的很详细,一些疑难点讲解的很详细。