- 题目:判断单链表是否有环,返回TRUE或者FALSE
- 难度:Easy
- 思路:定义两个指针fast和slow,两个指针同时从头移动,fast每次移动两步,slow每次移动一步,如果链表有环,则两个指针进入环之后,一定会在环的某点相遇
- 代码:
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null){
return false;
}
ListNode fast = head;//fast走两步
ListNode slow = head;//slow走一步
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
return true;
}
}
return false;
}
}
题目:如果链表有环,返回环的起始结点;如果没有环,则返回null
原题链接在这儿呀难度:Medium
思路:先判断链表是否有环(思路方法与#141一样,定义两个指针);如果链表有环,则让其中一种指针从head重新开始走,另一个指针从相遇点继续走,那么下一次相遇的点必然会是环的起点。
相遇点到环起点的距离 == head到环起点的距离 可自行通过画图证明
代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null){
return null;
}//这里注意:LeetCode认为只有一个节点,不算是环
ListNode fast = head;
ListNode slow = head;
boolean hasCycle = false;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
hasCycle = true;
break;
}
}
if(!hasCycle){
return null;
}
slow = head;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
拓展!!!!
- 题目:求环的长度
- 思路:当环相遇时,让两个指针继续以原来的节奏移动,同时这个时候开始计数,每移动一次count++;直到下一次相遇,结束计算。
- 代码:
public class Solution {
public int countCycleLen(ListNode head) {
if(head == null || head.next == null){
return null;
}
ListNode fast = head;
ListNode slow = head;
boolean firstMeet = false;
boolean secondMeet = false;
int len = 0;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast && secondMeet){
break;
}
if(slow == fast && !firstMeet){
firstMeet = true;
secondMeet = true;
}
if(secondMeet){
len++;
}
}
return len;
}
}
如何判断两个链表(不带环)是否相交?将其中的一个链表首尾相连,然后判断另一个链表是否带环即可