链表面试题9之环形链表进阶

那么上一题我们已经知道了双指针的变法以及拓展的用法,那么这里我们直接难度升级。

想回去复习的这里放个链接:链表的面试题8之环形链表-CSDN博客

题目链接:142. 环形链表 II - 力扣(LeetCode)

我们来看这道题目主要想让我们干什么,上一题是让我们去判断是否为环形链表,而这一题是直接告诉你这就是一个环形链表,让你自己去探寻环形链表各节点的关系,用地址来判断这个节点是否是第一个成环的节点。

当然这一题还是用双指针的解法,至于为什么很简单,单指针解决不了这个问题呗。我们上一题探讨过快慢指针的步调的大小,涉及快慢指针的算法题中,通常习惯使用快指针每次走两步,慢指针走一步的方式。

这里我们需要判断的难点是什么??

我们之前用到的快慢指针都是通过他们的距离差让这两个指针相遇来得出这个是环形链表,但是这里我们相遇的点万一不是第一个点呢??那么我们的判断不就成了无效判定了吗?所以我们笃定一点,这道题像上一道题那样的关系判断是不可取的,我们应该找其他的关系,使得让两个节点一定在第一个成环的节点相遇。

那我们直接来画图看一下:

这里我们设从头节点到入环的第一个节点的距离为a,设环长为c。

再设相遇的时候,慢指针走了b步,那么这里快指针就走了2b步。

再设快指针比慢指针多走了k圈环,那么我们就能得到2b-b=kc,即b=kc。

再看我们的慢指针,从头节点开始,到相遇点走了b-a步,也就是(kc-a)步。

这也就是说,从相遇点开始,再走a步,就会到达我们的入环点。

为什么?

因为环长就是c,看图中的箭头,一根箭头代表一个长度。所以再走a步,也就是说(kc-a+a)=kc步

也就是在入环口处。那么哪里还有a步的地方呢?

我再往图里一看,那就是头节点处,所以我如果让指针从头节点和相遇点处分别开始移动,那么两个人步伐都为1的情况下肯定会在入环口处相遇。

结论就是:让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。

但要注意一点:指针从相遇点开始,移动 a 步后恰好走到入环口,但在这个过程中,可能会多次经过入环口。 因为环长和入环前的长度可能会有误差。

cs 复制代码
struct ListNode* detectCycle(struct ListNode* head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow) { // 相遇
            while (slow != head) { // 再走 a 步
                slow = slow->next;
                head = head->next;
            }
            return slow;
        }
    }
    return NULL;
}

这里把代码贴一下,整个思路是非常清晰的,效率也非常高。

时间复杂度:O(n),其中 n 为链表的长度。

空间复杂度:O(1),仅用到若干额外变量。

这里再带大家注意两点推导设条件的前提:1.慢指针在进入环之前,快指针就已经在环内至少走了n圈,而n至少为1。因为快指针至少要走一圈,才能与后进入的慢指针相遇。

2.慢指针进环之后,快指针肯定会在慢指针走一圈之内追上慢指针
因为:慢指针进环后,快慢指针之间的距离最多就是环的长度,而两个指针在移动时,每次它们至今的距离都缩减一步,因此在慢指针移动一圈之前快指针肯定是可以追上慢指针的。

好了,这道题就讲到这里

如果你觉得对你有帮助,可以点赞关注加收藏,感谢您的阅读,我们下一篇文章再见。

一步步来,总会学会的,首先要懂思路,才能有东西写。

相关推荐
这张生成的图像能检测吗9 分钟前
(论文速读)探索多模式大型语言模型的视觉缺陷
人工智能·深度学习·算法·计算机视觉·语言模型·自然语言处理
এ᭄画画的北北19 分钟前
力扣-49.字母异位词分组
算法·leetcode
设计师小聂!20 分钟前
力扣热题100-------169.多数元素
java·数据结构·算法·leetcode·多数元素
拉不动的猪20 分钟前
jS篇Async await实现同步效果的原理
前端·javascript·面试
24 分钟前
LeetCode Hot 100 买卖股票的最佳时机
算法·leetcode·职场和发展
艾莉丝努力练剑35 分钟前
【数据结构与算法】顺序表和链表、栈和队列、二叉树、排序等数据结构的完整代码收录
c语言·数据结构·学习·链表
海绵波波10742 分钟前
基于OpenCV的cv2.solvePnP方法实现头部姿态估计
人工智能·opencv·算法
DolphinDB1 小时前
基于 CEP 引擎的算法拆单与调度实践—基础篇
算法
志如1 小时前
【校招面试官说】什么样的技术人更容易被大厂校招选中?
前端·后端·面试
啊阿狸不会拉杆1 小时前
《算法导论》第 3 章 - 函数的增长
开发语言·数据结构·c++·算法