LeetCode(142)——Linked List Cycle II

题目:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?


AC:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (null == head || null == head.next) {
            return null;
        }
        
        ListNode fastNode = head;
        ListNode slowNode = head;
        int cycleLen = 0;
        int pathLen = 0;
        int count = 0;
 
        while (null != fastNode && null != fastNode.next) {
            fastNode = fastNode.next.next;
            slowNode = slowNode.next;
            if (fastNode == slowNode) {
                break;
            }
        }
        
        if (fastNode != slowNode) {
            return null;
        }
        
        fastNode = fastNode.next;
        cycleLen = 1;
        while (fastNode != slowNode) {
            fastNode = fastNode.next;
            cycleLen++;
        }
        
        slowNode = head;
        while (slowNode != fastNode) {
            slowNode = slowNode.next;
            pathLen++;
        }
        
        if (cycleLen > pathLen) {
            count = cycleLen - pathLen;
            slowNode = head;
        }
        else {
            count = pathLen - cycleLen;
            fastNode = head;
        }
        
        while (count > 0) {
            fastNode = fastNode.next;
            count--;
        }
        
        while (fastNode != slowNode) {
            fastNode = fastNode.next;
            slowNode = slowNode.next;
        }
        
        return fastNode;
    }
}

该题为求链表如果存在圆的情况下,圆的入口节点。

假设该链表存在圆,如图所示:


图中标红的X点为快慢指针的相遇点,但是在该点相遇时,不知道快慢指针是第一次进圆时相遇,还是第n次进圆才相遇。

首先在相遇后,可以再次利用两指针,求出该圆的长度,即b+c。也可以求出从头节点到相遇点的距离,即a+b。这两个长度均为单次的结果,不存在多次绕圆的情况。两者的差值,即为a和c的差值,即为头节点到圆入口与相遇点到圆入口距离的差值,注意有可能a大,也可能c大。距离远者,先前进|a-c|,此时两节点到圆入口距离相同,同时移动,则相遇点即为圆入口。


PS:这题印象很深,当初校招面试某独角兽企业时,写出第141题,判断圆存在与否了,接着让我写出该圆的入口节点。当时天气炎热,加上紧张,头脑很混乱,只模糊的记着大致思路,却一直没写出来,很遗憾。还是自己不够熟练,需要勤加练习。



猜你喜欢

转载自blog.csdn.net/weixin_39120845/article/details/79458599