通过万岁!!!
-
题目:给你一个链表,然后链表中可能有环。如果有,则找到他的入环的节点。如果没有,则返回null。
-
思路:这个题我之前在leetcode101的书上看过。大致思路就是用到了双指针,然后正好今天刷到了,就再整理一下。
- 首先,如果没有环,那么快指针一定能先找到null,所以直接通过快指针判断即可。
- 然后主要是说一下有环的时候。首先看一下下面的图,我们假设head到目标节点的节点个数是x。然后快慢指针一定会相遇相遇的,相遇的位置为环内的第y个,也就是目标节点到第一次相遇的节点之间的节个数为y个。最后在定义环的节点个数是z个。
- 然后其实我们找到x即可。然后我们定义下公式,满指针到第一次相遇的地方一共走了x+y步,快指针走了(x+y) * 2。这个结果还等于x+y+n * z,其中n表示快指针绕了多少圈的环。所以我们有了公式(x+y) * 2=x+y+nz,即x=n * z-y。所以说,这时候我们让快指针到head的位置,然后两个指针都一步一步的走,直到两个相遇,这时候快指针走了x,慢指针从第一次相遇开始走了nz+y。这样就找到了目标节点。
-
技巧:快慢指针
java代码
public class Solution {
public ListNode detectCycle(ListNode head) {
//
if (head == null) {
return null;
}
// 先判断有没有环
ListNode f = head, s = head;
do {
if (f != null && f.next != null) {
f = f.next.next;
s = s.next;
} else {
return null;
}
} while (f != s);
// 找节点
f = head;
while (f != s) {
f = f.next;
s = s.next;
}
return s;
}
}
- 总结:题目挺有意思的,特别是这个公式推导。这种方法再次也进行一个总结。对于环形的问题,一个方法就是快慢指针。