单链表:链表中环的入口结点

链表中环的入口结点

题目:
      给出一个链表,找出该链表中环的入口结点。

示例:
       该链表中环的入口结点是 2在这里插入图片描述
思路:
      ① 判断链表是否为空或是否只有一个结点。

      ② 定义两个快慢指针,分别记作:fast、slow。每次让fast向前走两步,slow向前走一步。

      ③ 若fast和slow相遇,则说明链表中存在环,记相遇结点为meetNode。

      ④ 定义一个tmp引用,从链表的第一个结点出发,让tmp、meetNode以相同步长向前走,当tmp==meetNode时,tmp、meetNode共同指向的结点就是链表中环的第一个结点。

证明:
      X,Y,Z分别为链表起始位置,环开始位置和两指针相遇位置。慢指针的速度设为 x,则快指针的速度为2x。
快慢指针均从X出发,在Z相遇。此时,慢指针走的距离为:(a+b),快指针走的距离为: a+b+n(b+c)。
      所以, (a+b)/x = a+b+n(b+c)/2x,化简得:2*(a+b) = a+b+n*(b+c)
      推出:a = (n-1)b+nc = (n-1)(b+c)+c
      即将此两指针分别放在起始位置和相遇位置,并以相同速度前进,当一个指针走完距离a时,另一个指针恰好走出 n-1圈加c的距离。

代码实现:

public class Solution {
     
    public ListNode isCycle(ListNode head){
        if(head==null || head.next==null){
            return null;
        }
         
        ListNode slow = head;
        ListNode fast = head;
        while(slow!=null && fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                return slow;
            }
        }
        return null;
    }
     
    public ListNode detectCycle(ListNode head) {
         
        ListNode meetNode = isCycle(head);
        ListNode tmp = head;
        if(meetNode != null){
            while(tmp!=meetNode){
                tmp = tmp.next;
                meetNode = meetNode.next;
            }
            return meetNode;
        }
         
         
        return null;
         
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值