- 问题描述
寻找一个链表进入环的结点并进行返回.
如果无返回 null. - 解决思路
①设置两个引用 slow, fast.
②判断链表是否有环. slow 一次走一步, fast 一次走两步,
如果 fast == null , 说明链表无环, 返回空
如果 slow == fast , 说明走到某个结点两个相遇了, 此时链表有环.
这时将这设置两个引用 cur1, cur2, 使 cur1 引用指向链表头结点, cur2 的引用指向相遇结点. 两个引用 cur1, cur2 一次往后走一步, 直到两个引用 cur1, cur2 在往后走的过程中相遇, 相遇的这个结点就是入环的结点, 返回此节点. - 源代码
public class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
第一种写法
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null) {
return null;
}
ListNode meet1 = null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
meet1 = fast;
break;
}
}
// 没有环时 meet1 == null
if (meet1 == null) {
return null;
}
// 有环时 meet1 指向非空对象
ListNode cur1 = head;
ListNode cur2 = meet1;
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
}
第二种写法
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break;
}
}
if (fast == null || fast.next == null) {
return null;
}
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}