单链表L,头指针为phead,判断其是否有环
输入一个单链表:1,2,3,4,5->i2
最后->i2表示,下一下指针指向了index=2的(3)地址 输出1表示有环 输出0表示无环
import java.util.Scanner;
// 节点类
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 判断单链表是否有环
public static int hasCycle(ListNode head) {
if (head == null || head.next == null) {
return 0; // 没有节点或只有一个节点肯定没有环
}
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
if (slow == fast) {
return 1; // 快指针追上了慢指针,有环
}
slow = slow.next; // 慢指针走一步
fast = fast.next.next; // 快指针走两步
}
return 0; // 快指针到达了链表尾部,没有环
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 输入单链表,格式如:1,2,3,4,5->i2
String input = in.nextLine();
String[] parts = input.split("->");
// 构建单链表
ListNode head = null;
ListNode tail = null;
String[] values = parts[0].split(",");
for (String value : values) {
if (!value.isEmpty()) { // 确保 value 不为空
int num = Integer.parseInt(value);
ListNode node = new ListNode(num);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
}
}
}
// 如果有环,parts[1] 将包含 i2,表示环的起始点
if (parts.length > 1 && parts[1].length() > 1) {
int index = Integer.parseInt(parts[1].substring(1));
ListNode current = head;
while (index > 0 && current != null) {
current = current.next;
index--;
}
tail.next = current;
}
int result = hasCycle(head);
System.out.println(result); // 输出结果,1 表示有环,0 表示无环
}
}
此题该解法的关键点,在hasCycle(ListNode head)函数中慢指针走一步,快指针走两步的这一部分。如果有环,那快指针一定比慢指针先进入环,将指针移动方向作为正方向,在慢指针进入环的时候,快指针的位置为起始位置,快指针正方向距离慢指针的距离即为快指针追赶上慢指针的时间(因为每一次两个指针的距离减一),这也恰好保证在追赶一圈以内,能使快指针追赶上慢指针。