一:判断链表是否为带环链表
首先如何判断链表是否有环,这个时候首先需要知道链表是否为空,如果不为空,则继续判断。
思路:首先定义两个变量,一个fast,一个slow,让fast 每次走两步,slow每次走一步,当fast和slow相遇时,即是该链表存在环结构。如果该链表为无环结构,则当遍历完这个链表时也不会相遇。即是返回false。
判断条件: (fast != null && fast.next != null)
如果存在环形结构则如下图所示:
初始值都指向头结点 走第一步
走第二步 走第三步
当走到第三步的时候,发现fast和slow相等,所以返回值为true。该单链表为有环结构。
无环结构的判断:
判断条件: fast != null && fast.next != null
如果不存在环形结构则如下图所示:
初始值两值都指向头结点 走第一步
走第三步
当走到第三步的时候,发现fast.next为空,所以结束判断。如果当循环结束之后还没有返回,则是返回false。
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
return true;
}
}
return false;
}
}
二:寻找带环链表的环入口
如果链表为有环结构,则需要寻找到这个的入口,如何寻找到这个入口,可以看看下图讲解。
如图步骤:
第一步,fast和slow都指向头结点 第二步,fast走两步,slow走一步
第四步 第五步,fast和slow相遇,链表有环,此时将slow移回头结点位置
移回头结点之后的图 接着走,此时让fast和slow没都走一步
接下来就是一直同步走,直到再次相遇 再次相遇,此时slow和fast所指向的位置即是环的入口
寻找环的入口的代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
if(fast == null || fast.next == null){
return null;
}
slow = head;
while(fast != slow){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}