插个队 leetcode 142. 环形链表 II

leetcode 142. 环形链表 II

给定一个链表,返回链表开始入环的第一个节点。 若是链表无环,则返回 null。 为了表示给定链表中的环,咱们使用整数 pos 来表示链表尾链接到链表中的位置(索引从 0 开始)。 若是 pos 是 -1,则在该链表中没有环。 说明:不容许修改给定的链表。node

示例1:算法

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

在这里插入图片描述
示例2:

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

在这里插入图片描述
示例3:

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

在这里插入图片描述
这道题思路其实很简单,就是快指针每次前进两格,慢指针前进一格,相遇以后将fast置为头结点和slow每次各自前进一格,再次相遇即为环的起始位置。 OK,让咱们尝试来证实一下。 首先,咱们必须明确一点,若是链表有环,那么快慢指针必定会相遇。来咱们看图说话。
在这里插入图片描述
咱们设环外链表长度为X(固然有可能为0),从环的入口到相遇点的长度为Y,环的周长为C,那么当即推: 快指针走过的长度为 F = X + Y + n*C(n为快指针超了慢指针n圈) 慢指针走过的长度为 S = X + Y 由于: 1.快指针必定走的距离是慢指针的两倍。 2.若是X=0,则快指针正好跑了两圈,而慢指针跑了一圈,此时n=2但并不影响;若是X > 0,快指针总会在第二圈,即n = 1的时候追上慢指针,毕竟快指针先入环总归是比快慢指针同时入环要早一些相遇。(原谅我,这个是我看出来的,可是确定是能够证实的) 因此: 咱们看n=1的状况 X + Y + C = 2 ( X + Y ) 即: X = C - Y 如今咱们能够看出来,n=1这种状况下,若是咱们有两个指针,一个从头结点开始,一个从快慢指针相遇点开始,同时一步一步地走,那么新的相遇点就是环的入口啦。 特殊的状况n=2时,其实咱们能够看到快慢指针相遇点自己就是头结点。那么确定也是符合最上边的结论的。 上码吧老爷:

func detectCycle(head *ListNode) *ListNode {
    slow,fast:=head,head
    for{
    	//自始至终快慢未相遇,直接跳出就好
        if fast==nil||fast.Next==nil {
            break;
        }
        slow, fast = slow.Next,fast.Next.Next
        //相遇了就像刚刚说的那样咯
        if slow==fast {
            fast = head;
            for{
                if(slow==fast){
                    return slow
                }
                slow=slow.Next
                fast=fast.Next
            }
        }
    }
    return nil
    
}
复制代码

算法梦想家,来跟我一块儿玩算法,玩音乐,聊聊文学创做,我们一块儿天马行空! spa

在这里插入图片描述
相关文章
相关标签/搜索