zoukankan      html  css  js  c++  java
  • 链表中环的入口结点(剑指offer_23)

    题目描述


    一个链表中包含环,请找出该链表的环的入口结点。要求不能使用额外的空间。

    解题思路


    使用双指针,一个快指针fast每次移动两个节点,一个慢指针slow每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。

    假设环入口节点为y1,相遇所在节点为z1。

    假设快指针fast在圈内绕了N圈,则总路径长度为x + Ny +(N - y)z。 z为(N-1)倍是因为快慢指针最后已经在z1节点相遇了,后面就不需要再走了。

    而慢指针slow总路径长度为x+y。

    因为快指针是慢指针的两倍,因此x + Ny + (N-1)z = 2(x + y)。

    我们要找的是环入口节点y1,也可以看成寻找长度x的值,因此我们先将上面的等值分解为和x有关: x = (N-2)y + (N-1)z。

    上面的等值没有很强的规律,但是我们可以发现y + z就是圆环的总长度,因此我们将上面的等式再分解: x = (N-2)(y+z) + z。

    这个等式左边是从起点 x1 到环入口节点 y1 的长度,而右边是在圆环中走过 (N-2) 圈,再从相遇点 z1 再走过长度为 z 的长度。此时我们可以发现如果让两个指针同时从起点 x1 和相遇点 z1 开始,每次只走过一个距离,那么最后他们会在环入口节点相遇。

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead == null || pHead.next == null)
            return null;
        ListNode slow = pHead, fast = pHead;
        do{
            fast = fast.next.next;
            slow = slow.next;
        }while(slow != fast);
        fast = pHead;
        while(slow != fast)
        {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
  • 相关阅读:
    Python --- Python的简介
    Python---subline的安装与设置
    算法进阶指南(DFS和BFS)--- 小猫爬山
    算法进阶指南(递归)--- 递归实现排列型枚举
    算法进阶指南(递归)--- 递归实现组合型枚举
    算法进阶指南(递归)--- 递归实现指数型枚举
    linux命令行调试邮件服务器
    01_8_session
    01_7_cookies
    03_9_继承中的构造方法
  • 原文地址:https://www.cnblogs.com/ziytong/p/12123798.html
Copyright © 2011-2022 走看看