题目描述:给你一个链表的头节点 ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。nextpos,如果链表中存在环 ,则返回 。否则,返回 。truefalse
获得更多?算法思路:代码文档,算法解析的私得。
运行效果
完整代码
import java.util.HashSet;
import java.util.Set;
/**
* 2 * @Author: LJJ
* 3 * @Date: 2023/8/2 9:04
* 4
*/
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
this.next = null;
}
}
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null; // 链表为空或只有一个节点,不可能成环
}
ListNode slow = head;
ListNode fast = head;
// 使用快慢指针判断链表中是否有环
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break; // 快慢指针相遇,链表中有环
}
}
// 如果快指针或快指针的下一个节点为null,说明链表没有环
if (fast == null || fast.next == null) {
return null;
}
// 新建一个指针从链表头出发
ListNode ptr = head;
// 慢指针继续前进,新指针从链表头出发,它们相遇的节点就是链表开始入环的第一个节点
while (ptr != slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
head.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node2; // 这里构成环,节点5的next指向节点2
Solution solution = new Solution();
ListNode cycleStartNode = solution.detectCycle(head);
// 打印链表和循环开始节点
System.out.println("链表:");
printLinkedList(head);
System.out.println("循环开始节点的值为:" + cycleStartNode.val);
}
public static void printLinkedList(ListNode head) {
Set<ListNode> visited = new HashSet<>();
ListNode current = head;
while (current != null) {
if (visited.contains(current)) {
System.out.println("链表中存在环,无法完整打印链表。");
return;
}
System.out.print(current.val + " -> ");
visited.add(current);
current = current.next;
}
System.out.println("null");
}
}