原题
链表简单2 种解法

#234回文链表

判断单链表节点值从前向后与从后向前是否相同。

#链表#双指针#快慢指针

原题

给你一个单链表的头节点 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) 空间复杂度解决此题?

查看原题

解题主线

  1. 复制到数组后可直接使用首尾双指针。
  2. O(1) 额外空间方案用快慢指针找前半段末尾,反转后半段比较,最后恢复链表。

解法 1:数组 + 双指针

顺序收集节点值,再从数组两端向中间比较。

  • 时间复杂度: O(n)

  • 空间复杂度: O(n)

JAVA
final class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
    }
}

final class Solution {
    public boolean isPalindrome(ListNode head) {
        // 比较指针从序列两端同步向中间推进,任一对失配即可结束。
        // 奇数长度的中点无需配对,不影响回文判定。
        java.util.List<Integer> values = new java.util.ArrayList<>();
        for (ListNode node = head; node != null; node = node.next) values.add(node.val);
        int left = 0, right = values.size() - 1;
        while (left < right) {
            if (!values.get(left).equals(values.get(right))) return false;
            left++;
            right--;
        }
        return true;
    }
}

解法 2:反转后半段并恢复

定位前半段末尾,反转后半段后逐节点比较,再反转回来恢复输入。

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)

JAVA
final class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
    }
}

final class Solution {
    public boolean isPalindrome(ListNode head) {
        // 比较指针从序列两端同步向中间推进,任一对失配即可结束。
        // 奇数长度的中点无需配对,不影响回文判定。
        if (head == null) return true;
        ListNode firstHalfEnd = firstHalfEnd(head);
        ListNode reversed = reverse(firstHalfEnd.next);
        boolean palindrome = true;
        ListNode first = head;
        ListNode second = reversed;
        while (second != null) {
            if (first.val != second.val) {
                palindrome = false;
                break;
            }
            first = first.next;
            second = second.next;
        }
        firstHalfEnd.next = reverse(reversed);
        return palindrome;
    }

    private ListNode firstHalfEnd(ListNode head) {
        ListNode slow = head, 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 previous = null;
        ListNode current = head;
        while (current != null) {
            ListNode next = current.next;
            current.next = previous;
            previous = current;
            current = next;
        }
        return previous;
    }
}

边界与易错点

  • 比较 Integer 时应比较数值而非对象引用。
  • 原地反转方案若不恢复链表,会给调用方留下隐蔽副作用。

整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

  • easy/Q234_isPalindrome_linkedList.java