剑指 Offer II 022. 链表中环的入口节点

Posted 易小顺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer II 022. 链表中环的入口节点相关的知识,希望对你有一定的参考价值。

算法记录

LeetCode 题目:

  给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null。。



说明

一、题目

  为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

二、分析

  • 这个题有两个步骤需要求解。
  • 一是需要先判断是否存在环结构。
  • 二是求解出环的起点节点。
  • 我们在使用快慢指针进行判环求解时,快指针会比慢指针多走一倍的位置。假设在走了 A 步以后慢指针到达环的起点,这个时候可知快指针一定在距离环起点 A 步的距离。
  • 现在我们可以再次进行假设慢指针在走了 X 步后会被快指针给追上,这里我们就可以得到一个重要的信息,当前的快指针所处位置前进 X 步后会到达环的起点,也就是说环的长度为 A + X 步长。
  • 再换个方向来考虑,慢指针在距离环起点 X 步会被快指针追上,也就是说此时的位置距离环起点还有 A 步的距离,和链表起点距离环起点步长一致。
  • 得到上述的规则我们就可以在找到交点后让一个指针指向头结点,另一个指针不动,同时以相同的步长向前移动,直到相等即为环的起点。
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null || head.next == null)
            return null;
            
        ListNode first = head;
        ListNode second = head;
        
        while(first!= null && first.next != null){
            first = first.next.next;
            second = second.next;
            if(first == second)
                break;
        }
        
        if(first == second) {
            second = head;
            while(second != first) {
                second = second.next;
                first = first.next;
            }
            return second;
        }
        return null;
    }
}

总结

了解环起点和交点之间的距离关系。

以上是关于剑指 Offer II 022. 链表中环的入口节点的主要内容,如果未能解决你的问题,请参考以下文章

Java算法题解剑指 Offer II 022. 链表中环的入口节点

剑指offer 55.链表 链表中环的入口结点

剑指offer(五十六)之链表中环的入口结点

剑指OFFER 链表中环的入口结点

剑指offer:链表中环的入口节点

剑指offer-链表中环的入口结点