链表中环的入口结点-牛客BM7-使用到数学公式来解

链表中环的入口结点

题目:在这里插入图片描述

解题思路;

在这里插入图片描述

    思路:
    * 定义从头结点到环入口节点的距离为x
      从环入口出发到第一次相遇点的距离为y
      从相遇点出发到第一次相遇点的距离为z
    * 定义 快指针每次走两格,慢指针每次走1格
    * slow第一次相遇走的距离 = x + y
      fast第一次相遇走的距离 = x + n(y+z) + y
      由2slow = fast
      2(x + y) = x + n(y + z) + y
      x + y = n(y + z)
      因为小学追及问题快追慢,肯定大于一圈了,这个可以在图上自己画画,因此n大于等于1
      x + y = (n-1)(y+z) + y + z
      x = (n-1)(y+z) + y
      这里(y+z)就是环的距离
      因此得出x的距离 就是几倍环的距离 加上y的距离,而x的距离即为此题要的结果
      即让两个指针分别从头结点和相遇点开始走,相遇的时候即为入口到环口的位置
    * 解题步骤:
      1 找出第一相遇点的位置
      2 定义两个指针 分别从头结点和相遇点开始走,相遇的时候即为入口到环口的位置

代码:

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

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

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if (pHead.next == null) {
            return null;
        }

        //寻找第一个相遇点的index
        ListNode firstMeetNode = findFirstMeetNode(pHead);
        if (firstMeetNode == null) {
            //说明没得环
            return null;
        }

        //定义index1 指向头结点
        //定义index2 指向相遇点
        //让index1和index2 同时出发,第一次相遇点即为入口节点
        ListNode index1 = pHead;
        ListNode index2 = firstMeetNode;
        ListNode resultNode = findResultNode(index1, index2);

        return resultNode;
    }

    private ListNode findFirstMeetNode(ListNode pHead) {
        //寻找第一个相遇点的index
        ListNode slow = pHead.next;
        ListNode fast = pHead.next.next;
        while (fast != null) {
            if (fast.val == slow.val) {
                //相遇结点
                return fast;
            }
            slow = slow.next;
            if (fast.next == null) return null;
            fast = fast.next.next;
        }
        return null;
    }

    private ListNode findResultNode(ListNode index1, ListNode index2) {
        while (index1 != null && index2 != null) {
            if (index1.val == index2.val) {
                return index1;
            }
            index1 = index1.next;
            index2 = index2.next;
        }
        return null;
    }

}

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值