php实现找链表中环的入口节点(画图、看评论

一、总结

画图、看评论

二、php实现找链表中环的入口节点

题目描述:

一个链表中包含环,请找出该链表的环的入口结点。

三、代码

  • 第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
  • 第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。

不严谨,如果环比较小,在慢针没入环的时候,快针可能已经转了N久了

设起点到相遇点距离为x,起点到入口点距离为y,环长度为r,则快慢针相遇时,满足2x-x=nr,n为快针在环中转的圈数。--> x=nr
快慢针相遇点距环入口点距离x-y
相遇后,快针从起点重新开始以步长为1速度开始走,经过距离y到达环入口点,慢针走y步后距离环入口点距离为x-y+y=x=nr,即走到了环入口点,两个指针相遇

代码没有问题,但是数学证明不严谨

我来说明一下多走k圈和1圈其实是一样的:根据题目要求,找入口结点就相当于找倒数第n个结点,而倒数第kn个结点其实就是倒数第n个结点。所以这个题就变成找倒数第kn个结点,刚好p1已经走了kn个结点,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
这就说明不管是1圈还是k圈,结果是一样的,可以直接看成一圈来解答。

多走k圈和多走一圈是一样的,a是头结点到入口结点的距离,b是入口节点Y到相遇处Z的距离,c是环的长度减去b。
相遇时有:
S_{fast} = 2S_{slow}
假设相遇时pFast在环内转了k圈,则
a + k(b+c) + b = 2(a + b) 
移项得:
a = (k-1)(b+c) + c
说明头结点X到入口结点Y的距离等于从相遇处Z开始在环内转悠k-1圈(k >= 1)后,最后从Z到Y的距离。当k =1时候,a = c,此时pFast比pSlow多走一圈(也就是大家一直讨论的情况)

 public class Solution {
 
    ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead == null || pHead.next == null)
            return null;
        ListNode p1 = pHead;
        ListNode p2 = pHead;
        while(p2 != null && p2.next != null ){
            p1 = p1.next;
            p2 = p2.next.next;
            if(p1 == p2){
                p2 = pHead;
                while(p1 != p2){
                    p1 = p1.next;
                    p2 = p2.next;
                }
                if(p1 == p2)
                    return p1;
            }
        }
        return null;
    }
}

php实现找链表中环的入口节点(画图、看评论)的更多相关文章

  1. 剑指Offer:链表中环的入口节点【23】

    剑指Offer:链表中环的入口节点[23] 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 第一步确定链表中是否包含环,怎么确定呢?我们定义两个指针橙和 ...

  2. C++实现查找链表中环的入口节点

    /* * 寻找链表中环的入口节点.cpp * * Created on: 2018年4月10日 * Author: soyo */ #include<iostream> using nam ...

  3. 【剑指offer】面试题 23. 链表中环的入口节点

    面试题 23. 链表中环的入口节点

  4. 剑指offer(55)链表中环的入口节点

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 1.一快一慢指针,先找到碰撞点. 2.然后碰撞点到入口节点的距离就是头结点到入口节点的距离. 具体原理可 ...

  5. python剑指offer 链表中环的入口节点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...

  6. 剑指Offer(书):链表中环的入口节点

    题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. public ListNode EntryNodeOfLoop(ListNode pHead) { //第一步,查找是 ...

  7. 剑指offer——25链表中环的入口节点

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null.   题解: 使用快慢指针即可,若快慢指针会相遇,则有环,否则快指针先到空节点: 此时,快指针从此处一次移一步遍历, ...

  8. 剑指offer——面试题23:链表中环的入口节点

    函数: ListNode* MeetingNode(ListNode* pHead) { if(pHead==nullptr) return nullptr; ListNode* quickNode= ...

  9. [剑指Offer]23-链表中环的入口节点

    题目链接 https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&t ...

随机推荐

  1. 兔子--ps中的基本工具总结(ps cs5)

    矩形选框工具 椭圆选框工具 单行选框工具 单列选框工具 移动工具 套索工具柜 多边形套索工具 磁性套索工具 魔棒工具 高速选择工具 裁剪工具 切片工具 切片选择工具 吸管工具 颜色取样器工具 标尺工具 ...

  2. Linux下读写芯片的I2C寄存器

    要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...

  3. 11.Bean2Document-BEAN转document

    1. package com.glodon.gspm.adapter.plugin.common; import com.glodon.cloudt.tenancy.context.TenantCon ...

  4. 2.Java实现基于SOAP的XML文档网络传输及远程过程调用(RPC)-

    转自:https://blog.csdn.net/a214919447/article/details/55260411 SOAP(Simple Object Access Protocol,简单对象 ...

  5. JavaScript学习总结(2)——JavaScript数据类型判断

    最近做项目中遇到了一些关于javascript数据类型的判断处理,上网找了一下资料,并且亲自验证了各种数据类型的判断,在此做一个总结吧! 一.JS中的数据类型  1.数值型(Number):包括整数. ...

  6. [Javascript] Iterate Over Items with JavaScript's for-of Loop

    In this lesson we will understand the For Of loop in Javascript which was introduced in ES6. The for ...

  7. 3. Spring Boot Servlet

    转自:https://blog.csdn.net/catoop/article/details/50501686

  8. Traveler Nobita (zoj 3456 最小生成树)

    Traveler Nobita Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita used a time machin ...

  9. nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)

    题目999 题目信息 执行结果 本题排行 讨论区 师傅又被妖怪抓走了 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 话说唐僧复得了孙行者,师徒们一心同体,共诣西方.自宝 ...

  10. Android---- 获取当前应用的版本号和当前android系统的版本号

    Android 应用程序获得版本号 我们可以在AndroidManifest.xml中设置程序的版本号等,如android:versionName="1.0",那如果想在代码中获取 ...