链表是否有环?那么环的长度是多少?环的首尾节点是什么?
快慢指针计算。
1.判断指针是否存在环?
思路:如果存在环,快指针最后一定会和慢指针在环的某一处相遇
public static ListNode HaveCycle(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 fast; //返回相交的交点
}
return null;
}
2.判断环的起始位置:
思路:让快指针指向开头,让慢指针指向初次相遇处,再次遍历再次相遇时就可以找到第一个入环节点。(只不过这时的快慢指针移动速度是一样的了)。这是结论可以记住。
public static ListNode FirstNode(ListNode head){
ListNode fast = head;
ListNode slow = HaveCycle(head);
if(slow!=null){
while (fast!=slow){
fast = fast.next;
slow = slow.next;
return fast; //第一个入环节点
}else{
return null;
}
}
3.计算环的长度:
思路:只要在第一个相遇的节点处停住作为标识,让一个指针指向相遇的节点,开始遍历,每次遍历一个节点,就可以,直到遇到标识就可以知道环的长度是多少。
public static int CycleLength(ListNode head){
ListNode slow = HaveCycle(head);
if(slow==null) return 0;
ListNode temp = slow.next;
int len = 1;
while(temp!=slow){
len++;
temp = temp.next;
}
return len;
}