寻找单链表开始入环的第一个节点

mac2026-06-08  12

给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回null

分析过程: 如图,先假设有如上带环链表;并在头结点处定义一个fast和一个slow指针(快慢指针),每次让fast走两步,slow走一步;则在环中,它们会在B点相遇,A点则为链表入环的第一个节点。 1.假设链表长度为n;head到入口点A的距离为x;入口点A到相遇点B的距离为y; 2.因为fast所走的路程是slow所走路程的两倍,即有:fast = 2 * slow; 3.fast和slow相遇后,fast所走的路程为:链表的总长度加上入口点A到相遇点B的 距离,即:fast = n + y;slow走的路程为head到相遇点的距离,即:slow = x + y; 4.所以有: n + y = 2 * (x + y) 可得:n = x + x + y; 所以可知相遇点B到入口点A的距离也为x; 所以此时,我们可以让fast回到head,让fast和slow同时往后走,当它们相遇时,这个节点即为链表开始入环的第一节点。【因为head到入口点的距离和相遇点到入口点的距离相等,均为x】

代码实现:

class Node { public int data; public Node next; public Node(int data) { this.data = data; } public Node() { } } class LinkList { Node head = new Node(); public Node detectCircle() { Node fast = this.head;//定义fast指针 Node slow = this.head;//定义slow指针 while (fast != null && fast.next != null) { fast = fast.next.next;//fast走两步 slow = slow.next;//slow走一步 //二者相遇 if (fast == slow) { break; } } //链表无环的情况 if (fast == null || fast.next == null) { return null; } fast = this.head;//让fast回到head while (fast != slow) { fast= fast.next; slow = slow.next; } return fast; } }
最新回复(0)