142. 环形链表 II-M

142. 环形链表 II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

说明:不允许修改给定的链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

《142. 环形链表 II-M》
示例 2:

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
《142. 环形链表 II-M》

示例 3:

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

《142. 环形链表 II-M》

进阶:
你是否可以不用额外空间解决此题?

  • 分析
    判断环,再到找到入环点;两个指针,一个一次一步,一个一次两步,若有环,则最终都会进入环,速度快的最终会超过速度慢,一定会追上;怎么找到环的入口,直接一个指针从链头,一个从相遇点next,开始一次一步再次相遇的点就是入口。
    L+X+n*R=2(L+X)->L=R-X+(n-1)R,即n=1,有L=R-X,从相遇点开始走完剩下的R-X和从表头到环入口距离一样,这样就可以再用两个指针跑一次,相遇的位置即是入口。
    具体公式推导见环的入口点 原理理解
  • code
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */
func detectCycle(head *ListNode) *ListNode {
    var one *ListNode
    var two *ListNode
    one=head
    if head!=nil{
        two=head.Next
    }else{
        two=nil
    }
    for ;one!=nil&&two!=nil;{
        if one==two{
            break
        }
        one=one.Next
        if two.Next!=nil{
            two=two.Next.Next
        }else{
            return nil
        }
    }
    if two==nil{
        return nil
    }
    one=head;two=two.Next//一个从头,一个从相遇点,一次一步,则再次相遇就是环开始的点
    for one!=nil&&two!=nil{
        if one==two{
            return one
        }
        one=one.Next
        two=two.Next
    }
    return nil
}
    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/scylhy/article/details/88723200
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞