创建两个指针p1和p2,让他们同时指向这个链表的头节点,然后开始一个大循环,在循环体中,让指针p1每次向后移动一个节点,p2每次向后移动两个节点,然后比较两个指针指向的节点是否相同。如果相同,则可以判断出链表有环,如果不同,则继续下一次循环。
public static boolean isCycle(Node head){
Node p1 = head;
Node p2 = head;
while (p2!=null&&p2.next!=null){
p1 = p1.next;
p2 = p2.next.next;
if (p1==p2){
return true;
}
}
return false;
}
问题拓展1---求环的长度
当两个指针首次相遇,证明链表有环的时候,让两个指针从相遇点继续循环前进,并统计前进的循环次数,直到两个指针第二次相遇。此时,统计出来的前进次数就是环长。环长=每一次速度差×前进次数=前进次数。
返回0那可能有点问题,代码也几乎类似
/**
* 求相遇节点并返回
* @param head
* @return
*/
public static Node length(Node head) {
Node p1 = head;
Node p2 = head;
int num = 0;
while (p2 != null && p2.next != null) {
p1 = p1.next;
p2 = p2.next.next;
int i = 1;
if (p1 == p2) {
return p1;
}
}
return null;
}
/**
* 获取环长
* @param head 传入的相遇节点
* @return 返回环长
*/
public static int TLong(Node head){
//拿到相遇节点
Node node1 = length(head);
Node p1 = head;
Node p2 = head;
int num = 0;
while (p2 != null && p2.next != null) {
p1 = p1.next;
p2 = p2.next.next;
num++;
if (p1 ==p2){
return num;
}
}
return 0;
}