剑指offer 22. 链表中环的入口结点

简介: 剑指offer 22. 链表中环的入口结点

题目描述

给定一个链表,若其中包含环,则输出环的入口节点。

若其中不包含环,则输出null


数据范围

节点 val 值取值范围 [1,1000]。

链表长度 [0,500]。

样例

599cebb262e543e1813f1ed36b1d4ccf.png

给定如上所示的链表:
[1, 2, 3, 4, 5, 6]
2
注意,这里的2表示编号是2的节点,节点编号从0开始。所以编号是2的节点就是val等于3的节点。
则输出环的入口节点3.


方法一:链表,快慢指针扫描 O(n)


这道题的思路很有趣,通过数学公式可以推出下面的结论(假设有环):


设置 slow 和 fast 指针从 head 开始往后遍历,直至 fast 和 slow 再次相遇才停止。

从 head 开始往后遍历,同时 slow 继续往后遍历,直至两个指针相遇为止就是环的入口地址。

我们就拿题目的样例来举例,看看具体是如何实现的:


第一步: 设置两个快慢指针 i 和 j 。


0499d4cfab814a36a145c76a58d47f54.png第二步: 慢指针每次只往后走一个结点,快指针每次往后走两个结点,直至两指针相遇才停止移动。


d3dc11710e5f434384b101521f9af8a1.png88248b3b354245a58fefd18c4842df58.png3086271a468e4802bccabc0d9f3f1b73.png

9ba14a16ed374b0682f4cf3e478fb911.png

第三步: 当两指针相遇后,再创建一个指针指向头结点,和指向当前相遇结点的指针一起往后移动,每次移动一个结点指针两结点相遇,再次相遇的结点就是该链表的入口结点。

b9c69729cdfe45dc9b137e1117aaa196.png73e5a5bc7bd14cd39986c930290caa6c.png



bd7675a83a814d568a3eb07ea0afb7d4.png


第四步: 返回入口结点,即结点 3

注意:如果该链表没有入口结点,则快指针会直接遍历到空结点去,导致循环中断,这时直接返回 NULL 即该链表没有入口结点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* entryNodeOfLoop(ListNode* head) {
        ListNode* slow = head, * fast = head;
        while (fast != NULL) {
            if (fast->next == NULL)    return NULL;
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow) {
                ListNode* cur = head;
                while (cur != slow) {
                    slow = slow->next;
                    cur = cur->next;
                }
                return cur;
            }
        }
        return NULL;
    }
};


欢迎大家在评论区交流~

目录
相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
69 1
|
25天前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
13 1
|
2月前
链表的中间结点
链表的中间结点
178 57
|
1月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
49 0
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
6月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
5月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
5月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
56 2
|
6月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
53 1