[链表]8.链表中环的入口节点[阿里巴巴,招银网络]

对于一个给定的链表,返回环的入口节点,如果没有环,返回null

拓展:

你能给出不利用额外空间的解法么?

解答:

类似于追及问题:

  1. 如何判断有环的存在?
    在追及问题中,我们可以用两个速度不同的物体从同一地点出发,如果相遇则证明存在环(可用反证法证明,若不存在环,则速度不同的物体从同一地点出发则一定不会相遇),因此可以类比过来,定义两个指针fast、slow,令两指针以不同速度向后指,则相遇时证明有环存在,若fast指向NULL,则不存在环。

  2. 怎么找到环的入口结点?
    首先说方法:在问题一中两指针相遇后,让一个指针从头结点开始,另一个从相遇结点开始,并以相同速度向后指,再次相遇时就是环的入口结点。

证明:
1)假设存在环,fast以速度2运行,slow以速度1运行,在slow走到入口t时,如图(m1为在slow首次到t时fast的位置,a为h到t的距离,b为t到m1的距离,n为环的周长):

由图知fast走的距离为a+b+xn,slow走的距离为a,又v(fast) = 2*v(slow),所以x(fast) = 2*x(slow),即2a = a+b+xn,因此a = b+xn
m1逆时针到t的距离为n-b。

2)在首次相遇时,如图(m2为相遇点):

由于m1逆时针到t的距离为n-b,即要达到相遇需要追赶n-b的距离,由于两者速度差为1,因此需要n-b的时间才能相遇,此时slow再次向后n-b距离,即到达m2位置与fast相遇,因为一周长度为n,因此到t的距离为 n-(n-b) = b

3)为何令slow重新从pHead以速度1开始走,令fast从m2以速度1走?要想在入口t相遇,则需要从m2处再走b+yn的距离,刚好pHead处符合(由1)可知,同时因为是一个环,所以即使相差整数圈的距离也是在圈的同一个位置),所以令slow从pHead开始走。在相遇后就是入口t的位置。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
         
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                slow = head;
                while(slow != fast){
                    slow = slow.next;
                    fast = fast.next;
                }
                break;
            }
        }
        if(fast == null || fast.next == null ) return null;
        return slow;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值