1、判断是否有环
https://leetcode-cn.com/problems/linked-list-cycle/
思路,快慢指针,快指针先于慢指针入环,然后相遇
public boolean hasCycle(ListNode head) {
ListNode fast,slow;
fast = slow = head;
while (slow!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == null || fast == null) return false;
if(slow == fast) return true;
}
return false;
}
2、获取环的入口节点
https://leetcode-cn.com/problems/linked-list-cycle-ii/
推导公式:
2*S = s+n*r
s = n*r
a + x = s = n*r
a + x = (n-1)*r + r = (n-1)*r + (L-a)
a= (n-1)*r + (L-a -x)
代码:
public static ListNode detectCycle(ListNode head) {
ListNode fast, slow;
fast = slow = head;
while (slow!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == null || fast == null) return null;
if(slow == fast) break;
}
if(slow == null || fast.next == null) return null;
while (head != slow){
head = head.next;
slow = slow.next;
}
return head;
}
3.得到环的节点数
public int getCircleSize(ListNode head){
ListNode fast,slow;
fast = slow = head;
while (slow!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow ==null || fast == null) return 0;
if(slow == fast) break;
}
if(slow == null || fast.next == null) return 0;
ListNode temp = slow.next;
int count = 1;
while (temp != slow){
temp = temp.next;
count++;
}
return count;
}
4 得到单链表长度
public int getLinkListSize(ListNode head){
ListNode fast,slow;
fast = slow = head;
int count = 0;
boolean isCircle = false;
while (slow!=null && fast.next!=null){
count++;
slow = slow.next;
fast = fast.next.next;
if(slow ==null || fast == null){
isCircle = false;
break;
}
if(slow == fast) {
isCircle = true;
break;
}
}
if(isCircle){ //如果是环,链表节点个数 应该是 到环入口节点数 + 环的节点数
ListNode p = head;
ListNode q= slow;
int startCount = 0; //链表起点到 环入口节点数(不包含环入口节点)
while (p != q){
startCount++;
p = p.next;
q = q.next;
}
ListNode temp = slow.next;
int circleCount = 1; //环节点数
while (temp != slow){
temp = temp.next;
circleCount++;
}
return startCount + circleCount;
}else{
while (slow!=null){
count++;
slow = slow.next;
}
return count;
}
}