链表中环的入口节点

《剑指offer》面试题23:链表中环的入口节点

题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路:
  原书中给出的思路:解决问题的第一步是如何确定一个链表有环。我们可以用两个指针来解决这个问题。定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走的快的指针追上了走得慢的指针,那么链表就包含环;如果走的快的指针走到了链表的末尾都没有追上第一个指针,那么链表就不包含环。
  第二步是如何找到环的入口。我们还是用两个指针来解决这个问题。先定义两个指针p1和p2指向链表的头节点。如果链表的环中有n个节点,则指针p1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口节点时,第一个指针已经围绕着环走了一圈,又回到了入口节点。
  剩下的问题是如何得到环中节点的数目。我们在前面提到判断一个链表里是否有环时用到了一快一慢两个指针,如果两个指针相遇,则表明链表中有环。两个指针相遇的节点一定是在环中。可以从这个节点出发,一边继续向前移动一边计数,当再次回到这个节点时,就可以得到环中节点数了。
  可以进行优化的地方:如何得到环中节点的数目n?在判断链表是否有环时用到了一快一慢两个指针,如果它们相遇,则表明链表中有环。相遇时走的快的指针走的步数刚好比走的慢的指针走的步数多n步。这相当于运动学上的追击问题,追上的条件是刚好多走“一圈”,在这里可以在两个指针走的过程中对指针走的步数分别进行计数,当它们相遇时,计数之差就是环中节点的数目。对比书中给出的解法:不用在得到相遇节点之后再走n步得到n。减少了常量级别的时间复杂度。
  勘误:之前认为在求环中节点数目n时可以利用运动学中的追击问题的特性进行时间复杂度上的优化,但在与同学的讨论中发现之前的思路是错误的,之前认为在判断链表是否有环时用到的一快一慢两个指针相遇的条件是快指针刚好多走"一圈",但实际上是多走了n圈,之前在思考的过程中将两个指针想象成两个人在操场跑步进行追击,人跑步的相遇条件确实是"一圈",但两个指针一快一慢的"走","擦肩而过"并不叫相遇,只有当两个指针指向同一节点时才是真的相遇。

代码如下:

public ListNode EntryNodeOfLoop(ListNode head) {
    // 得到相遇节点
    ListNode meetingNode = getMeetingNode(head);
    if (meetingNode == null) {
        return null;
    }
    // 计算环中节点总数
    int count = 1;
    ListNode node1= meetingNode.next;
    while (node1 != meetingNode) {
        node1 = node1.next;
        count++;
    }
    // 让node1指针先走count步,node2再与node1一起走
    node1 = head;
    ListNode node2 = head;
    for (int i = 0;i < count;i++) {
        node1 = node1.next;
    }
    while (node1 != node2) {
        node1 = node1.next;
        node2 = node2.next;
    }
    // 相遇点即为环的入口节点
    return node1;
}

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

推荐阅读更多精彩内容