标准答案
- 遍历链表,把当前节点的 next 暂存为 next,再将 current.next 指向 previous。
- 移动 previous 和 current,直到 current 为空,previous 就是新的头节点。
- 时间复杂度是 O(n),额外空间复杂度是 O(1);不能在改指针前丢失后继节点。
题目解析
每次循环只处理一个节点:先把 current.next 保存下来,再把 current.next 指向 previous,最后整体向后移动。保存后继是正确性的关键,否则原链表剩余部分会丢失。
空链表返回 null,单节点会自然返回原节点;奇偶长度不改变算法。若题目要求保留原链表,还要改用新节点或栈,并重新说明空间复杂度。
迭代版本的时间复杂度是 O(n),额外空间是 O(1),递归版本虽然代码短,但会使用 O(n) 调用栈,并可能受到栈深限制。
代码示例
迭代实现只需要三个指针:
TypeScript
function reverse<T extends { next: T | null }>(head: T | null) {
let previous: T | null = null
let current = head
while (current) {
const next = current.next
current.next = previous
previous = current
current = next
}
return previous
}常见误区
- 误区:先改 next 再保存后继节点。改正:必须先保存后继引用,再改变指针。
- 误区:空链表时直接访问 head.next。改正:先判断 head 是否为空,空链表应返回 null。
- 误区:用数组或递归实现却仍声称空间 O(1)。改正:把辅助数组或调用栈计入额外空间。