剑指offer 链表中环入口结点(哈希表/双指针)

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

下面给出两种方法,分别使用哈希表和双指针
双指针示意图如下图所示
在这里插入图片描述

/*
   使用 hashMap 返回第一次出现的重复结点
*/
public ListNode EntryNodeOfLoop1(ListNode pHead){
   HashMap<ListNode,Integer> hashMap = new HashMap<>();
   ListNode pnode = pHead;
   while (pnode != null){
       hashMap.put(pnode, hashMap.getOrDefault(pnode, 0)+1);
       if (hashMap.get(pnode) == 2)
           return pnode;
       pnode = pnode.next;
   }
   return null;
}
/*
示意图在上面

指针 slow fast: slow 一次走 一步,fast 一次走 2 步;
设从链表开始到环入口距离为 s,当快慢指针相遇时,slow 在环里走了 d 步,环长度为 d+ m
设此时快指针走了 n 圈 , n(m+d) +d + s = 2(s+d)
化简一下上述式子则有 n(m+d) = s+ d
s = n*m + (n - 1)*(m+d)
*/
public static ListNode EntryNodeOfLoop2(ListNode pHead){
   if (pHead == null)
       return null;
   ListNode slow = pHead;
   ListNode fast = pHead;
   //寻找环
   while (fast != null && fast.next != null){
       fast = fast.next.next;
       slow = slow.next;
       if (fast == slow)
           break;
   }
   if (fast == null || fast.next == null)
       return null;

   //在找到环的相遇点
   slow = pHead;
   while (fast != slow){
       fast = fast.next;
       slow = slow.next;
   }
   return fast;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值