链表中环的入口结点(题号23)

问题描述:

给一个长度为n的链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。

数据范围: n≤1000

要求:空间复杂度 O(1),时间复杂度 O(n)

解题思路:

  1. hash

    遍历所有节点,将节点地址依次存储在一个hash表中,等走完环形部分回到环的入口节点处,此时hash表中已经存储过所有节点,经过判断是否存在该节点会返回true,则该节点就是入口节点,直接返回即可。

    时间复杂度:O(n)

    空间复杂度:O(n)

    该方法因为空间复杂度不满足要求,所以不做重点讲解

  2. 双指针法

    初始化两个节点指向链表头结点,一个步进快的fast,一个步进慢的slow,设定fast节点每次步进两步,slow节点每次步进一步。当两个节点第一次相遇(指向同一个节点,此时在环中)的时候,将其中一个节点重置为指向头结点然后分别以一为步长重新步进,待两个节点重新相遇,则被指向的节点就为环的入口节点。

    时间复杂度:O(n)

    空间复杂度:O(1)

    下面着重讲解该方法

注意事项:

跳出循环的判断条件以及跳出第一次循环后判断是否是正常跳出:正常跳出则返回null,表示没有环,打断则继续第二个循环

论证

  • 结论一:两个节点第一次相遇一定指向环中的节点

    显然节点的步进速度一快一慢,这里的设定是快速节点是慢速节点速度的两倍,所以假如链表没有环,则慢速节点永远无法追上快速节点与其相遇,所以反推两节点能相遇必然链表中存在环并且相遇的节点只能在环中。

  • 结论二:重置其中一个节点指向头结点后分别以一为步长重新步进,待两个节点重新相遇,则被指向的节点为环的入口节点

    image

    (图片内容仅用于抽象说明问题)

    如上图a:

    |ad|=a,|dg|=b,|gd|=c

    快指针路程=a+(b+c)k+b,k>=1,其中b+c为环的长度,k为环的圈数(k>=1,即最少一圈,不能是0圈,不然快慢指针走的路程一样,矛盾)。

    慢指针路程=a+b

    因为快指针的路程是慢指针的路程的两倍,所以:(a+b)*2=a+(b+c)k+b

    化简得:

    a=(k-1)(b+c)+c,这个式子的意思是:链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈数环长度。其中k>=1,所以k-1>=0圈。所以两个指针分别从链表头和相遇点出发,最后一定相遇于环入口。

    该证明引用自:知乎

代码

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode fast = pHead;
        ListNode slow = pHead;
        // 快速节点终止循环的条件是当前指向的节点为空或者当前节点的下一个节点为空
        while (fast != null && fast.next != null) {
            // 每次步进两步
            fast = fast.next.next;
            // 每次步进一步
            slow = slow.next;
            // 代表两节点第一次相遇
            if (fast == slow) {
                break;
            }
        }
        // 正常退出循环代表该链表无环,所以返回null
        if (fast == null || fast.next == null) {
            return null;
        }
        // 选择一个节点重置到链表头节点位置
        fast = pHead;
        // 分别重新以步长为一的速度步进直到两个节点重新相遇,终止循环
        while (fast != null && fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        // 返回相遇位置的节点即为环的入口
        return slow;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 思路 可以使用快慢指针的思想...
    youzhihua阅读 202评论 0 0
  • 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 思路 先分两步考虑,怎么判断...
    就这些吗阅读 124评论 0 0
  • 代码很简单,主要是理论。 设起点到入口距离为a,入口到相遇点为b,相遇点到入口(正向)为c 则有 2(a+b) =...
    ZYHAzwraith阅读 146评论 0 0
  • 《剑指offer》面试题23:链表中环的入口节点 题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则...
    打工这件小事阅读 287评论 0 1
  • 首先介绍下自己的背景: 我11年左右入市到现在,也差不多有4年时间,看过一些关于股票投资的书籍,对于巴菲特等股神的...
    瞎投资阅读 5,717评论 3 8