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

 1 package algorithms;
 2 
 3 /*
 4 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
 5  
 6  public class ListNode {
 7     int val;
 8     ListNode next = null;
 9 
10     ListNode(int val) {
11         this.val = val;
12     }
13 }
14 */
15 
16 /*
17  *     首先判断链表中是否有环 思路是用两个指针,同时从链表的节点出发
18  *     一个走的慢,一个走的快
19  *     如果两个指针不能相遇则无环,否则有环
20  * 
21  *     如何找到环的入口?
22  *     还是先定义两个指针,p1,p2
23  *     n代表链表中环的节点个数    
24  *     p1先向前移动n步
25  *     然后两个指针以相同的速率向前移动
26  *     两个指针相遇的地方就是环的入口地址(总结规律出来的)
27  * 
28  *     接下来就是如何求环中节点的个数
29  *     两个指针相遇的地方一定是在环的内部  
30  *     所以可以从这个节点出发,边走边计数
31  *     当再次回到这个节点的时候  就知道环中节点的个数了
32  * */
33 public class EntryNodeOfLoop {
34 
35     public ListNode EntryNodeOfLoop_1(ListNode pHead) {
36         //返回相遇的节点
37         ListNode meetingNode = meetingNode(pHead);
38         if (meetingNode == null)
39             return null;
40         int countOfLoop = 1;
41         ListNode node1 = meetingNode.next;
42         //求出圈的长度
43         while (node1 != meetingNode) {
44             countOfLoop++;
45             node1 = node1.next;
46         }
47         //p1向前移动圈长的长度
48         node1 = pHead;
49         for (int i = 0; i < countOfLoop; i++) {
50             node1 = node1.next;
51         }
52         //两个节点同时向前移动  相遇的地方就是圈的开始
53         ListNode node2 = pHead;
54 
55         while (node1 != node2) {
56             node1 = node1.next;
57             node2 = node2.next;
58         }
59 
60         return node1;
61 
62     }
63 
64     // 判断链表中是否有环 并找到相遇的节点
65     ListNode meetingNode(ListNode pHead) {
66         if (pHead == null)
67             return null;
68         ListNode slowNode = pHead;
69         ListNode fastNode = slowNode.next;
70         while (fastNode != null && slowNode != null) {
71             if (fastNode == slowNode)
72                 return fastNode;
73             slowNode = slowNode.next;
74             fastNode = fastNode.next;
75             if (fastNode != null)
76                 fastNode = fastNode.next;
77         }
78         return null;
79 
80     }
81 }

 

转载于:https://www.cnblogs.com/ustc-anmin/p/10609321.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值