直接回答:最直观的做法是把值复制到数组后双指针对撞,时间 O(n)、空间 O(n)。进阶要求是 O(1) 空间:快慢指针找到中点,反转后半段链表,与前半段逐点比较,最后(可选)把后半段再反转恢复结构。
展开解析:O(1) 空间版本把三个基础操作串成了一条流水线:1)快慢指针找中点——fast 每次两步、slow 每次一步,fast 到尾时 slow 在中点(注意奇偶长度的处理);2)反转链表——迭代三指针;3)双头比较。任何一步单独拿出来都是独立面试题,所以这道题常用来考察基本功的组合运用。易错点:奇数长度时中点节点不属于任何一半、比较只需走完较短的一半、以及面试中如果允许改结构才用反转法,否则应说明副作用。追问方向:如何用递归(调用栈当栈)实现 O(n) 空间的优雅写法、回文判断扩展到「重排链表」「回文对」等变体。
示例:
def is_palindrome(head):
slow = fast = head
while fast and fast.next:
slow, fast = slow.next, fast.next.next
prev = None # 反转后半段
while slow:
slow.next, prev, slow = prev, slow, slow.next
left, right = head, prev
while right:
if left.val != right.val:
return False
left, right = left.next, right.next
return True