题目介绍
翻转环形链表
题解
- 检测链表是否有环并找到环的入口:力扣原题
- 将环断开:在找到环的入口后,通过设置指针记录环的信息,然后将环断开,使其成为一个普通的单链表。
- 反转单链表:
- 重新连接环:在完成链表反转后,根据之前记录的环的入口信息,重新将链表连接成环。
代码如下:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class CircularLinkedList {
// 检测环形链表并返回环的入口节点
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) {
// 找到环后,重置慢指针到头部
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow; // 返回环的入口节点
}
}
return null; // 无环
}
// 普通链表翻转
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
// 带环链表翻转
public ListNode reverseListWithCycle(ListNode head) {
ListNode cycleEntry = detectCycle(head);
// 如果不是环形链表,直接翻转
if (cycleEntry == null) {
return reverseList(head);
}
// 找到环入口的前一个节点
ListNode p = head;
while (p.next != cycleEntry) {
p = p.next;
}
// 断开环
p.next = null;
// 翻转链表
ListNode newHead = reverseList(head);
// 重新连接环
ListNode tail = newHead;
while (tail.next != null) {
tail = tail.next;
}
tail.next = cycleEntry;
return newHead;
}
// 测试方法
public static void main(String[] args) {
// 创建测试链表 1->2->3->4->5->2 (形成环)
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; // 形成环
CircularLinkedList solution = new CircularLinkedList();
// 检测环
ListNode cycleNode = solution.detectCycle(head);
System.out.println("环入口节点值: " + (cycleNode != null ? cycleNode.val : "无环"));
// 翻转带环链表
ListNode reversedHead = solution.reverseListWithCycle(head);
// 打印翻转后的链表(注意:由于有环,不能直接遍历打印,会无限循环)
// 这里只打印前几个节点作为演示
System.out.print("翻转后的链表前几个节点: ");
ListNode current = reversedHead;
for (int i = 0; i < 6 && current != null; i++) {
System.out.print(current.val + " ");
current = current.next;
}
}
}