题目
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:

输入:head = [1,2,2,1]
输出:true
示例 2:

输入:head = [1,2]
输出:false
提示:
- 链表中节点数目在范围
[1, 105]内 0 <= Node.val <= 9
进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
题解
class Solution public boolean isPalindrome(ListNode head) {
if (head null || head.next == null) {
return true; // 空链表或只有一个节点的链表是回文
}
// 找到中间节点
ListNode mid = findMiddle(head);
// 反转后半部分链表
ListNode secondHalf = reverseList(mid.next);
ListNode firstHalf = head;
// 比较两个部分
boolean isPalin = true;
ListNode p1 = firstHalf;
ListNode p2 = secondHalf;
while (p2 != null) {
// 只需比较后半部分的长度
if (p1.val != p2.val) {
isPalin false;
break;
}
p1 = p1.next;
p2 = p2.next;
}
}
//找链表中点(偶数链表找前中点)
private ListNode findMiddle(ListNode head) {
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow; // slow是中间节点
}
//反转链表
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
思路
- 找到链表的中间节点。
- 反转链表的后半部分。
- 比较前半部分和反转后的后半部分是否相同。