剑指offer——链表中环的入口节点

继续链表。原题目链接:链表中环的入口节点

题目描述:

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

题目分析:

首先需要判断链表中是否有环;其次是寻找入口节点。

相关内容需要推导,详细过程可参见博客:单链表面试题系列之带环链表的入口点。这个博客也很清晰明了:Java--链表中环的入口节点(两种方法实现)

这里直接采用结论。

如何判断链表是否有环:设置快慢指针,slow和fast。slow每次走一步;fast每次走两步。若链表带环,则两个指针必然会相遇,且相遇点必然在环内

判断是否有环的方法实现如下:

 1     public boolean judge_ring(ListNode pHead){
 2         ListNode slow = null;
 3         ListNode fast = null;
 4         slow = fast = pHead;    //刚开始都指向第一个节点
 5         
 6         while(fast!=null && fast.next!=null){
 7             slow = slow.next;   //每次走一步
 8             fast = fast.next.next;  //每次走两步
 9             if(slow == fast){
10                 return true;    //若有环,则必定会相遇
11             }
12         }
13         return false;   //若直接走到头,则没有环
14     }

如何寻找入口节点:设置两个指针,分别从表头和相遇点出发,每次走一步,则必然会在环入口相遇

利用此结论,便可得到本题的解决方案,实现代码如下所示:

 1     public ListNode EntryNodeOfLoop(ListNode pHead){
 2         ListNode slow = null;
 3         ListNode fast = null;
 4         slow = fast = pHead;    //刚开始都指向第一个节点
 5 
 6         while(fast!=null && fast.next!=null){
 7             slow = slow.next;   //每次走一步
 8             fast = fast.next.next;  //每次走两步
 9             if(slow == fast){
10                 break;    //若有环,则必定会相遇
11             }
12         }
13         if(fast==null || fast.next==null){
14             return  null;   //若没有相遇,则无环
15         }
16         ListNode meet = fast;   //记录相遇节点
17         slow = pHead;      //重新回到第一个节点
18 
19         while(slow!=meet){  //一定会相遇在入口节点
20             meet = meet.next;
21             slow = slow.next;
22         }
23         return meet;
24     }

 

posted @ 2020-05-28 21:12  暮光乐鱼  阅读(111)  评论(0编辑  收藏  举报