103. 带环链表 II

描述

给定一个链表,如果链表中存在环,则返回到链表中环的起始节点,如果没有环,返回null。

样例

给出 -21->10->4->5, tail connects to node index 1,返回10

挑战

不使用额外的空间

思路

本题更像一道数学题,判断是否有环用典型的快慢指针方法就可以解决,此处主要说怎么找到环的入口,设环的长度为 r,快指针的速度是慢指针的 2 倍,两个指针在第k步(可能已经绕环若干圈)相遇时,2k - k = nr 即 k = nr,设链表起始点到环的入口点(包括环的入口点)的距离是 s ,从环的起始点开始(不包含起始点)到相遇点的距离是 m (注意此处的 m 可能是包含若干个整圈距离再加上一个不足圈的环入口点到相遇点的距离) ,m + s = k 即 s = k - m => s = nr - m,那我们可以得出结论从快慢指针的相遇点往前出发走 s 步正好是环入口的上一个结点

代码

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    public ListNode detectCycle(ListNode head) {
        // 空结点或者不带环的单独结点 return null
        if (head == null || head.next == null) {
            return null;
        }

        ListNode fast, slow;
        fast = head.next;
        slow = head;
        // 先判断是否存在环
        while (fast != slow) {
            if (fast == null || fast.next == null) {
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
        } 
        
        // slow 和 head 正好差一个结点,当 head 是环入口时,slow 是环入口的上一个结点
        while (head != slow.next) {
            head = head.next;
            slow = slow.next;
        }
        // 也可写 return slow.next;
        return head;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转载请注明出处:http://www.jianshu.com/p/c65d9d753c31 在上一篇博客《数据结构...
    Alent阅读 8,821评论 4 74
  • 链表问题是面试过程中经常被问到的一部分,很考查编程功底。最近刷了 LeetCode 上链表部分的面试题,我总结了一...
    JohnnyShieh阅读 10,389评论 0 9
  • //leetcode中还有花样链表题,这里几个例子,冰山一角 求单链表中结点的个数----时间复杂度O(n)这是最...
    暗黑破坏球嘿哈阅读 5,415评论 0 6
  • 大学的时候不好好学习,老师在讲台上讲课,自己在以为老师看不到的座位看小说,现在用到了老师讲的知识,只能自己看书查资...
    和珏猫阅读 5,312评论 1 3
  • 文/笔迹 2003年10月的某天,正在职校读书的我参加了来校招工企业的面试,种种关卡下来,我顺利通过初试,笔试,回...
    笔迹故事阅读 1,183评论 2 2