class ListNode //链表节点定义
{
int val;
ListNode next;
public ListNode(int val) {
super();
this.val = val;
this.next = null;
}
}
public boolean existCircle(ListNode head) //判定链表是否有环
{
if(head==null)
return false;
ListNode fast,slow;
fast = slow = head;
while(fast!=null)
{
fast = fast.next;
if(fast==null)
break;
fast = fast.next;
slow = slow.next;
if(fast==slow) //若快慢指针相遇,则说明存在环
return true;
}
return false;
}
public ListNode findJoint(ListNode head) //查找连接点
{
if(head==null)
return null;
ListNode fast,slow;
fast = slow = head;
while(fast!=null)
{
fast = fast.next;
if(fast==null)
return null;
fast = fast.next;
slow = slow.next;
if(fast==slow) //如果存在环
{
ListNode p = head;
while(p!=slow) //p从链表头往后扫描,slow从碰撞点往后扫描
{
p = p.next;
slow = slow.next;
}
return p; //找到连接点
}
}
return null; //不存在连接点
}
public int circleLen(ListNode head) //判定链表环长度
{
ListNode p = this.findJoint(head);
if(p==null) //若不存在环,则返回长度0
return 0;
ListNode slow = p.next;
int count = 1;
while(slow!=p)
{
slow = slow.next;
count++;
}
return count; //返回环长度
}
public int listLen(ListNode head) //返回链表(可能有环)长度
{
if(head==null)
return 0;
ListNode p = this.findJoint(head);
int count = 0;
if(p==null) //若该链表无环,则直接遍历计数即可
{
p = head;
while(p!=null)
{
p = p.next;
count++;
}
return count;
}
int circleLen = this.circleLen(head);
ListNode t = head; //若链表有环,则链表长度=非环部分长度+环长度
while(t!=p)
{
t = t.next;
count++;
}
return count+circleLen;
}