题目描述
判断单链表是否为回文(正读反读一样)。要求 O(1) 额外空间。
思路解析
把值全存进数组、再首尾双指针比对,简单但要 O(n) 空间。想要 O(1) 空间?三步走:① 快慢指针找中点;② 把后半段原地反转;③ 前半、后半同时往中间比。
这题就是 876 找中点 和 206 反转链表 的合体。反转后半段之后,从原链表头和反转后的尾两头往中间走,逐个比值,全相等就是回文。
① 快慢找中点 · 起步:第一步,用快慢指针找中点:slow 走 1 步、fast 走 2 步,都从头出发。
① slow→2, fast 越界停:slow 一步步走到下标 2(第二个 2),fast 两步两步早就冲出链表(变 null),循环停。slow 此刻把链表分成前半 [1,2] 和后半 [2,1],后半从 slow 开始。
② 反转后半段 [2,1] → [1,2]:第二步,用 206 的三指针把后半段反转:下标 2、3 之间的箭头掉头(变 ←),后半从 2→1 变成 1→2。反转后后半段的新头是最后那个 1(下标 3)。
③ 左右双指针 · 第一对:第三步比较:left 从原头 1(下标0)、right 从反转后半的头 1(下标3)。比第一对:1 == 1 ✓。
③ 第二对 · left→2, right→2:left 沿正常箭头到下标1(值2),right 沿反转后的箭头到下标2(值2)。比第二对:2 == 2 ✓。两个指针就要相遇,比较结束。
全部相等 · 是回文:每一对都相等,返回 true。(只要中途有一对不等,立刻 false)
难题往往是基础招式的拼装:找中点 + 反转 + 双指针。熟练的小套路,是解决大问题的积木——这正是「套路模板」的价值。
参考代码(Python)
1slow = fast = head
2while fast and fast.next: # ① 找中点
3 slow, fast = slow.next, fast.next.next
4prev = None # ② 反转后半段
5while slow:
6 slow.next, prev, slow = prev, slow, slow.next
7left, right = head, prev # ③ 两头比较
8while right:
9 if left.val != right.val: return False
10 left, right = left.next, right.next
11return True复杂度分析
- 时间复杂度:O(n) —— 找中点+反转+比较都是线性
- 空间复杂度:O(1) —— 只用几个指针,不开数组
套路模板
记住骨架:快慢找中点 → 从中点起反转 → prev 是后半新头。重排链表(143)、判回文都靠这套「中点+反转」组合拳。
1slow = fast = head
2while fast and fast.next: # 快慢找中点
3 slow, fast = slow.next, fast.next.next
4prev = None # 反转后半段
5while slow:
6 slow.next, prev, slow = prev, slow, slow.next
7# 现在 prev 是后半段反转后的头易错点
- ❌ 比较时走完整条链 → ✅ 以 right(后半) 是否到头为准(前半可能比后半多一个(奇数长度),走完会越界)
- ❌ 忘了找中点要先反转再比 → ✅ 严格按 找中点→反转→比较 三步(顺序乱了就比错位置)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。