中:链表的环

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

解:

这道题如果用O(n2)做法,可以直接根据每个节点是否能回到本节点或是末尾来判断环入口,代码也较为简洁,当然你需要从链表尾部倒着开始,否则会死循环。

这里介绍一种比较巧妙的做法,可以在O(n)时间内完成。我们根据以往的“操场追赶”经验,速度快的总是能在环里追上速度慢的,而如果不存在环,那么速度快的会直接跑到终点,而非相遇。所以我们只需要设置一个快节点,一个慢节点,每次快一步,如果有环就会相遇。那么环入口就需要计算了,我们根据数学关系可知,设起点到入口为x,相遇点距离入口y(未走段),那么显然快节点走过的路程是(x+n圈环-y)慢节点走过的路程为(x+m圈环-y),同时快=2*慢,那么就有(x+n圈环-y)=2*(x+m圈环-y),化简,x=y+k圈环,所以如果我们让一个节点从头走起,让一个在环内循环走,那么第一次相遇就会是在入口处。

建议自己画个图感受一下。

代码:

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead==null || pHead.next==null || pHead.next.next==null){
            return null;
        }
        ListNode slow=pHead.next;
        ListNode fast=pHead.next.next;
        while(slow!=fast){
            if(slow==null || fast.next==null){
                return null;
            }
            slow=slow.next;
            fast=fast.next.next;
        }
        slow=pHead;
        while(slow!=fast){
             slow=slow.next;
             fast=fast.next;
        }
        return slow;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值