代码随想录算法训练营41期 day4 链表02

24. 两两交换链表中的节点

这种改动链表结构的题,用上dummyHead就很方便统一其各种情况。

19.删除链表的倒数第N个节点

要找到链表中的倒数第N个节点时,双指针法是最快的。一开始没想到双指针,还把整个链表遍历了一遍算长度。

面试题 02.07. 链表相交

用双指针法,让两个指针对齐后在两个链表中同步向前遍历,两个指针相遇就说明找到了相交点。今天出错的点是双指针对齐后同步向前的部分:

while(curA->next!=nullptr){
//这样写忽略了输入为空的情况,curA->next此时是无意义的
//正确写法是while(curA!=nullptr)

            if(curA->next==curB->next) return curA->next;
            //这个错和前面的错是串联的,while条件改对了之后,此写法会导致不能正确识别不相交的情况
            //正确写法是if(curA==curB) return curA;
            curA=curA->next;

            curB=curB->next;

        }

142.环形链表II

一看到这个题,首先就想到了用哈希表,这样把环形遍历完就能找到环的入口,但是空间消耗大

而快慢指针法可以把空间复杂度降到O(1),难点在数学部分,遇到这种题要明确目标,从而在繁杂的变量里梳理出思路。

为什么要用快慢指针法?我觉得背后的原理是,快慢指针“匀速、倍速”的运动模式,在环形上会呈现出“无论绕了多少圈,总是会在环上的同一个点相遇”的特点,从而创造出一个不变量作为解题的锚点。找到一个不变量之后,就可以想一想,“找入口”的目标能不能往这个不变量上靠?我们要处理的这个链表里有三个关键的节点:已知的起点(头节点),目标节点(入口点),位置固定的特殊点(相遇点),后续的变量设置自然要围绕这三个点展开。

于是我们设起点到入口的距离为x,入口到相遇点的距离为y,相遇点回到入口的距离为z,相遇之前快指针已经绕过的完整圈数为n,再结合快慢指针的速度差异,列出方程,化简得到我们要求的x的表达式:

2(x+y)=x+n(y+z)+y

x+y=n(y+z)

x=n(y+z)-y

x=(n-1)(y+z)+z

接下来的重点是理解这个式子的物理意义。由于我们的链表结构是固定的,所以这里的n并不是一个可以随意取值的变量,而是一个未知的常量。也就是说这个式子揭示了这样的一个关系:从头节点到环入口的距离,恰等于相遇点到环入口的距离加上 环周长*某个常数。虽然我们不知道这个常数(圈数)具体是多少,但我们只要让一个指针(指针A)一直在这个环里转圈,同时让另一个指针(指针B)以相同的速度从头节点沿着链表运动,就能确保当B走过x距离到达环入口的时候,A离自己在环上的出发点距离是z,而z恰好是已经找到的相遇点和待求的入口点之间的距离。因此只要令指针A从环上的相遇点出发,就能确保它和从头节点出发以相同速度运动的指针B在环的入口相遇。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值