142 环形链表 II
题目:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
不仅要判断是否有环,还要找到入环的第一个节点
思路:
在上一道题中已经知道如何判断一个链表有没有环。即采用快慢指针法,如果相遇则有环。进一步思考:两个指针相遇的节点一定在环中。可以从这个结点出发,一边继续移动一边计数,当再次回到这个节点时,就可以得到环中节点个数了。
知道了节点个数n。我们可以让快指针先向前移动n步。然后两个指针一起移动。当第慢指针指向环的入口节点时,快指针也已经围绕着环走了一圈,回到了入口节点,两指针相遇
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public class Solution { public ListNode detectCycle(ListNode head) { ListNode meetnode = meetingNode(head); if(meetnode == null) return null; int nodeinLoop = 1; ListNode cur = meetnode; while(cur.next != meetnode){ cur = cur.next; nodeinLoop++; } ListNode fast = head; for(int i = 0; i < nodeinLoop; i++) fast = fast.next; ListNode slow = head; while(fast != slow){ fast = fast.next; slow = slow.next; } return fast; } public ListNode meetingNode(ListNode head){ if(head == null) return null; ListNode fast = head; ListNode slow = head; while(fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow) return fast; } return null; } }
|