24. 两两交换链表中的节点
题目链接/文章讲解/视频讲解: 代码随想录
也是画个图很容易就出来了。注意的是更换 next 的步骤的先后顺序,要保证在更更换一个节点的 next 之前,先将该节点赋给另一个节点的 next(如果需要的话)。此外,使用虚拟头结点,会方便很多。
19.删除链表的倒数第N个节点
题目链接/文章讲解/视频讲解:代码随想录
遍历两边的话很简单,先遍历一遍求链表长度,然后再遍历一遍,计数然后删除。如果想遍历一遍就实现,是双指针的经典操作。若希望删除倒数第 n 个节点,先让快指针走 n 步,然后让快慢指针同时移动,当快指针走到 None 时,慢指针指向的节点就是倒数第 n 个节点。
为了方便操作,我们让快指针先走(n+1)步,这样当快指针走到最后一个节点时,慢指针指向被删除节点的前一个节点,让 slow.next = slow.next.next 即可。
使用虚拟头节点会更方便。
面试题 02.07. 链表相交
题目链接/文章讲解:代码随想录
难点是思考如何找到交叉点。首先算出两个链表的长度,然后将两个链表从尾部对齐,对齐后从短链表的头节点位置开始寻找,逐个比对两个链表中的节点,如果有节点是一样的,说明两个链表在此节点处相交。“简单来说,就是求两个链表交点节点的指针。” 这里要注意,交点是指针/节点相等,而不是数值相等。
![](https://img-blog.csdnimg.cn/54a3e0366faf477fa1778681ea77e8db.png)
142.环形链表II
题目链接/文章讲解/视频讲解:代码随想录
首先用经典双指针判断是否有环:快指针和慢指针同时从头节点出发,快指针每次向前走两步,慢指针每次向前走一步。若有环,快慢指针定会相遇。若不相遇,则无环。
判断出有环之后,考虑两指针相遇的位置。两指针若相遇,则一定在环内相遇。假设头指针到环的起始位置的距离为 x,环开始的位置顺时针距两指针相遇的位置 y,两指针相遇的位置顺时针距离环起始位置 z。则慢指针走的路程为(x+y),快指针走的路程为(x+y+n*(y+z))。由此得出 2*(x+y)=(x+y+n*(y+z))。化简后得 x =(n-1)*(y+z) + z,也就是说,如果将慢指针放在头节点,将快指针放在相遇节点,两者都每次走一步的话,再次相遇的位置即是环开始的位置。(这个感觉莫名其妙有点像是“ 19.删除链表的倒数第N个节点 ”的那个感觉,不知道为啥。)