import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head ListNode类
     * @return bool布尔型
     */
    public boolean isPalindrome (ListNode head) {
        // write code here
        if (head == null || head.next == null) {
            return true;
        }

        ListNode mid = findMiddle(head); // 找到链表中点
        ListNode secondHalf = reverse(mid.next); // 反转后半部分链表
        mid.next = null; // 切断链表

        ListNode p1 = head; // 前半部分链表的指针
        ListNode p2 = secondHalf; // 后半部分链表反转后的指针

        while (p1 != null && p2 != null) {
            if (p1.val != p2.val) {
                return false;
            }
            p1 = p1.next;
            p2 = p2.next;
        }

        return true;
    }

    private ListNode findMiddle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        return slow;
    }

    private ListNode reverse(ListNode head) {
        ListNode prev = null;
        ListNode current = head;

        while (current != null) {
            ListNode nextNode = current.next;
            current.next = prev;
            prev = current;
            current = nextNode;
        }

        return prev;
    }
}

题目考察的知识点是链表的处理和判断回文的方法。

  • 定义一个辅助类 ListNode,表示链表的节点。节点包含一个整数值 val 和一个指向下一个节点的指针 next。
  • 定义一个 Solution 类,其中包含一个 isPalindrome 方法来判断链表是否为回文。
  • 在 isPalindrome 方法中,首先判断链表是否为空或只有一个节点,若是,则直接返回 true,因为单个节点的链表必定是回文的。
  • 定义两个指针 slow 和 fast,初始时都指向链表的头节点 head。使用快慢指针的方式找到链表的中点,即让 slow 每次移动一步,fast 每次移动两步,当 fast 到达链表末尾时,slow 刚好到达链表的中点。
  • 反转链表的后半部分。定义一个指针 secondHalf,初始时指向中点的下一个节点 mid.next。然后,通过迭代将 secondHalf 指针指向的节点逐个反转,即将当前节点的 next 指针指向前一个节点,然后依次向后移动 secondHalf 指针和前一个节点的指针。
  • 切断链表,将链表从中点处断开,即将 mid.next 设置为 null。
  • 分别使用两个指针 p1 和 p2 遍历链表的前半部分和反转后的后半部分,逐个比较节点的值。如果所有节点的值都相同,则链表为回文;否则,链表不是回文。
  • 若一直比较完所有节点都相同,则返回 true;否则,返回 false。