首页 > 其他分享 >力扣《环形链表Ⅱ》超详细题解

力扣《环形链表Ⅱ》超详细题解

时间:2023-05-07 14:04:14浏览次数:50  
标签:力扣 题解 next 链表 带环 pk pm 指针

作为经典题目的《环形链表Ⅱ》,我认为这题还是有专门出一期博客的分量的,大家也可以自己事先按照自己的理解写一写,然后再来看题解,毕竟自己悟出来的东西是比吸收别人的来的更深刻。

一、题目

  • 给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
  • 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
  • 不允许修改 链表。

二、思路

  • 首先要确定是否带环
  • 再找入环口

确定不带环很好写,设置一个指针,只要指向空了,那就一定是不带环的,那带环该怎么办呢?

示例:

力扣《环形链表Ⅱ》超详细题解_链表

如图所示,这是一个带环的链表,我们可以设置快慢指针来做这题,快指针每次走两步,慢指针每次走一步,发挥你的空间想象力,假设两个指针都进环了,那快指针每次都比慢指针多走一步,总会慢慢追上慢指针的。

上面是确定带环的思路,好了,现在是怎么找入环口,那怎么找呢?这就要有点数学底子了,先找关系,设快指针的路程为X1慢指针的路程为X2,我们可以把入环前面的路程设为X,从入环口到相遇的位置设置为a,从相遇的位置到入环口为b,如图所示:

力扣《环形链表Ⅱ》超详细题解_快慢指针_02

剩下的就是找关系了

  • 先看X1X1 = X + n *(a + b) + an代表走了几圈。再看X2X2 = X + a这个就更容易理解了。
  • 再找X1X2的关系:因为快指针每次是走的两步,慢指针每次一步,所以他们两个是二倍的关系,那就可以联立方程组了:
  • X1 = X + n(a + b) + a
  • X2 = X + a
  • X1 = 2X2

所以可得:X + a = n(a + b)

再设圈的长度是N,可得:X + (N - b)  = N * n,化简得:X =  N(n - 1) + bn表示圈数,先考虑一圈的情况,也就是n = 1,可得:X = b。   再考虑很多圈的情况,这个方程的意思就是X的距离,就是圈数再加上b的距离,那我们可得,不管他走了几圈,反正再多走b的距离,就是X的总距离。

所以,思路就有了:我们可以让它们两点在相遇之后,让一个指针重新从起始位置开始走,再次碰头,就是入环口。

三、代码实现

public ListNode detectCycle(ListNode head) {
    if (head == null) {
        return null;
    }
    ListNode pk = head;//快指针设置成pk
    ListNode pm = head;//慢指针设置成pm
    //不仅仅是pk本身不能为空,pk的下一个也不能为空,不然pk的下两个会越界
    while ((pk != null) && (pk.next != null)) {
        pk = pk.next.next;
        pm = pm.next;
        if (pk == pm) {
            pm = head;
            while (pk != pm) {
                pk = pk.next;
                pm = pm.next;
            }
            return pm;
        }
    }
    return null;
}

四、运行结果:

力扣《环形链表Ⅱ》超详细题解_开发者_03

内存和时间大家图一乐就行,内行人dddd(懂的都懂)

五、总结

总的来说,力扣《环形链表Ⅱ》虽然是一道难度适中的题目,但是在实际编码过程中还是有一些需要注意的细节,比如如何判断是否存在环、如何找到环的起点等。通过本篇超详细题解的阅读,相信大家已经对这个问题有了一个更加清晰的认识。

六、结语

编程之路,不仅仅是一道又一道题目的挑战,更是一场修炼自我的过程。力扣《环形链表Ⅱ》这道题目,虽然难度不高,但却需要我们在实战中不断探索,不断优化解法。编程之路亦是如此,唯有持之以恒、不断努力,才能够在道阻且长的路途中不断前行,逐渐成为一名优秀的程序员。相信无论你是初学者还是有一定经验的开发者,在不断攀登编程高峰的同时,也能够从力扣的各种题目中汲取营养,不断提升自己的技能水平。

力扣《环形链表Ⅱ》超详细题解_开发者_04

标签:力扣,题解,next,链表,带环,pk,pm,指针
From: https://blog.51cto.com/bitzmbdp/6251906

相关文章

  • CF1829B 题解
    题目思路先定义变量\(t,ans\)。循环从\(0\)到\(n-1\),对于第\(i\)个数,如果为\(0\),\(t=t+1\),否则将\(t\)清零。每次循环\(ans=\max(ans,t)\)表示最多有多少个连续的\(0\)。最后输出\(ans\)即可。核心代码点击查看代码voidsolve(){intn=read(),a[1005],a......
  • AtCoder Regular Contest 159简要题解
    AtCoderRegularContest159传送门A-CopyandPasteGraph图的邻接矩阵为\[\left(\begin{matrix}A&A&\cdots&A\\A&A&\cdots&A\\\cdots&\cdots&\cdots&\cdots\\A&A&\cdots&A\e......
  • P8655 [蓝桥杯 2017 国 B] 发现环 题解
    题目概述题目传送门在一棵树中新增一条边,使得这个图产生一个环,求在环上的点。思路:拓补排序对于这道题显然不能生搬硬套拓补排序的模板。这道题中的图是一个无向图,而拓补排序却是处理有向图的一种思想。不难想到可以将无向图转化为有向图,即将对于每条无向边变换为双向建边,就......
  • ABC297F 题解
    容斥萌萌题给你一个\(H\timesW\)的棋盘,问在棋盘上随机撒\(k\)个点,能够围住这\(k\)个点的最小子矩形的期望面积考虑枚举子矩形可以直接转成计数问题转变为在\(n\timesm\)的矩形中撒\(k\)个点,有多少种方案使得四条边上均至少有一个点答案乘上矩形面积再除以所有撒点......
  • BM3 链表中的节点每k个一组翻转
    描述将给出的链表中的节点每k 个一组翻转,返回翻转后的链表如果链表中的节点数不是k的倍数,将最后剩下的节点保持原样你不能更改节点中的值,只能更改节点本身。 数据范围:0≤n≤2000 ,1≤k≤2000 ,链表中每个元素都满足 0≤val≤1000要求空间复杂度 O(1),时间复杂度 O(n)......
  • BM2 链表内指定区间反转
    描述将一个节点数为size链表m 位置到 n位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)。例如:给出的链表为 1→2→3→4→5→NULL, m=2,n=4,返回 1→4→3→2→5→NULL. 数据范围: 链表长度 0<size≤1000,0<m≤n≤size,链表中每个节点的值满足 ∣val∣≤10......
  • BM1 反转链表
    描述给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。 数据范围: 0≤n≤1000要求:空间复杂度 O(1) ,时间复杂度 O(n) 。 如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。以上转......
  • Mac M系列芯片 vue前端node-sass兼容问题解决
    0、由于M系列芯片是arm架构,在使用brew安装node时都是arm的node,但是[email protected]版本中不支持arm架构的出现如下报错:Error:NodeSassdoesnotyetsupportyourcurrentenvironment:OSXUnsupportedarchitecture(arm64)withUnsupportedruntime(88)Formoreinfor......
  • LVJR2 赛后题解
    赛后补题请到洛谷比赛。A考虑分类讨论。显然当\(a=0,b=0\)时,答案等于\(0\)。当\(a=0\)或\(b=0\)时,直接将等于\(0\)的数乘以一个很大的数字,将不等于零的数除以一个很大的数字,答案为\(v\)。当\(a,b\)均不为\(0\)时,可以选择先将一个数字减到\(0\),或将一个数字除......
  • LeetCode 24. 两两交换链表中的节点
    题目链接:LeetCode24.两两交换链表中的节点本题不涉及算法,直接模拟就可以了,但是模拟的过程中,最好进行画图演示,不然容易出错。想要达到两两交换链表中节点的效果,就需要按照以下三个步骤进行。同时为了将头结点和非头结点统一处理,因此新建一个虚拟头结点,初始时,cur指向虚拟头结......