链表中环的入口结点

一、问题描述

   一个链表中包含环,请找出该链表的环的入口结点。

二、算法思想

    1.判断链表是否为空;

    2.判断是否存在环:用fast和slow两个指针,从head开始,一个走一步,一个走两步,如果最终到达同一个结点,则说明存在环;

    3.寻找环的入口:假设入口结点距离头结点a个单位,fast和slow相遇在距离入口结点b个单位的位置,环剩下的长度为c,则有a+b+c+b = 2*(a+b) -> a = c 。因此,在重合时候,将fast置为head,再一步一步地走,当fast再次与slow重合时的结点即为入口结点。

三、代码实现

Python实现

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        # 1.判断链表是否为空
        if pHead == None or pHead.next == None:
            return None
        # 2.定义fast和slow两个指针指向头结点
        fast = slow = pHead
        # 3.当指针指向不为空时
        while(fast and fast.next):
            # 慢指针走一步
            slow = slow.next
            # 快指针走两步
            fast = fast.next.next
            # 4.如果快、慢指针重合,则说明存在环
            if slow == fast:
                # 5.置fast为head结点从头走,slow位置不变
                fast = pHead
                # 6.当fast未与slow重合时,循环走
                while(fast != slow):
                    # 此时fast和slow都一步一步走
                    fast = fast.next
                    slow = slow.next
                # 7.直到fast与slow重合,重合的结点就是环的入口结点,返回该结点
                return fast
        return None

Java实现

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
      //1.判断链表是否为空
        if(pHead == null || pHead.next == null){
            return null;
        }
        //2.定义fast指针和slow指针指向头结点
        ListNode slow = pHead;
        ListNode fast = pHead;
        //3.指针指向不为空时
        while(fast != null && fast.next != null){
            //慢指针走一步
            slow = slow.next;
            //快指针走两步
            fast = fast.next.next;
            //4.如果快、慢指针重合,则说明存在环
            if(slow == fast){
                //5.置fast为head结点从头走,slow位置不变
                fast = pHead;
                //6.当fast未与slow重合时,循环走
                while(fast != slow){
                    // 此时fast和slow都一步一步走
                    fast = fast.next;
                    slow = slow.next;
                }
                //7.直到fast与slow重合,重合的结点就是环的入口结点,返回该结点
                return fast;
            }
        }
        return null;
    }
}

四、测试用例

(待测试)

功能测试:

1.没有环的链表

2.有环的链表

边界测试:

1.只有一个节点的链表

2.整个都是环的链表

极端测试:

链表头节点为null

五、拓展

https://blog.csdn.net/u012534831/article/details/74231581

如果要求环的长度,可以这样做:

当两者相遇之后,固定一个指针,让另一个指针行走一圈,使用count计数,如果两个指针相等(即相遇),则count即为环的长度。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值