142. Linked List Cycle II-巧

难点在于不使用额外空间

解法思路如下:(参考https://discuss.leetcode.com/topic/58134/o-n-time-and-o-1-space-java-solution-with-chinese-explanation
步骤一:通过Linked List Cycle的方式,则快慢指针(快指针一次两步,慢指针一次一步)相遇时,则表示存在环,且相遇点在环上。
步骤二:如果环存在,记:
c表示从head到环起始点的距离;
s表示从环起始点到快慢指针相遇点的距离;
cycle表示环的长度;
distance(pointer)表示指针走过的距离;
性质:
a)快指针走过的距离是慢指针走过距离的二倍
b)快指针和慢指针会相遇,是因为快指针已经套了慢指针一圈(且套第一圈时就会相遇,因为快指针快追上慢指针时,相距要么为1要么为2,为1时,下一次移动后相遇,为2时,在经过两次移动相遇)
于是有:
distance(slow)=c+s, distance(fast)=2(c+s)
性质a和b -> distance(fast)-distanc(slow)=k * cycle=2(c+s) - (c+s) = c+s; k = 1 or 2
-> c = k * cycle - s (k = 1 or 2)
又由于:环长度为cycle,两指针距离环起点距离为s,在走k*cycle-s则重新到达起点;且c为从head到环起点的距离,所以从head经过距离c会到达环起点,又c=k*cycle - s;所以用两个指针,同时从快慢指针的相遇点和head出发,每次移动距离为1,经过k*cycle - s(不论k==1还是k==2)会在环起点相遇。

代码如下 :

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = 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;
                }
                return slow;
            }
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值