貌似国内面试经常问得题目,以前没遇到过。。
思路:
1: 两个指针,一个一次走两格,一个一次走一个。相遇了证明有环。
2: 然后因为快的那个总是比慢的那个走快一步,当他们相遇后,再走k步(k是circle的结点数量)后,他们会再相遇,从而求出circle结点数量。
3: 最后再设置两个指针(都是一次走一步),但一开始一个比另外一个领先k步,那么它们就会刚好在环的起点相遇。。
但是偶在初始化那里接连犯了好几个错误。
该题目的另外一个变形:“两个链表,求相交的第一个节点”。
import java.util.*; class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } } public class Solution { ListNode dCycle(ListNode head) { if(head == null || head.next == null) return null; ListNode pSlow,pFast; pSlow = head; pFast = head.next; while(pFast.next != null && pFast.next.next != null && pFast != pSlow) { pFast = pFast.next.next; pSlow = pSlow.next; } if(pFast.next == null || pFast.next.next == null) return null; return pFast; } int CycleN(ListNode cnode) { ListNode pFast,pSlow; pSlow = cnode.next; pFast = cnode.next.next; int k = 1; while(pFast != pSlow) { pFast = pFast.next.next; pSlow = pSlow.next; k++; } return k; } public ListNode detectCycle(ListNode head) { if(head == null) return null; else if(head.next == null) return null; ListNode cNode = dCycle(head); if(cNode == null) return null; int iCycleN = CycleN(cNode); ListNode pAdvNode = head; ListNode pNode = head; for(int i=0;i<iCycleN;i++){ pAdvNode = pAdvNode.next; } while(pAdvNode != pNode) { pAdvNode = pAdvNode.next; pNode = pNode.next; } return pNode; } public static void main(String[] args) { Solution sol = new Solution(); ListNode n1,n2,n3; n1 = new ListNode(1); n2 = new ListNode(2); n3 = new ListNode(3); n1.next = n2; n2.next = n3; ListNode bNode = sol.detectCycle(n1); System.out.println(bNode); } }