题目描述
给定一个单链表的头节点 head 和两个整数 left、right,反转链表中从位置 left 到 right 的节点,并返回反转后的链表。要求只用一次遍历。
示例:
- 输入:
head = [1,2,3,4,5],left = 2,right = 4 - 输出:
[1,4,3,2,5]
约束条件:
1 ≤ n ≤ 500(n为节点个数)-500 ≤ Node.val ≤ 5001 ≤ left ≤ right ≤ n
常见思路与分析
1. 借助栈法
利用栈或数组暂存区间节点或者指针,然后两两配对交换节点值。这种方法本质上是"空间换时间",但每对节点都需要遍历链表两次,效率相对较低,且空间复杂度 O(k)(k为区间长度)。原链表结构未改变,缺乏链表操作的"原地特性"。
2. 双指针遍历法
每次从头分别定位到 left 和 right,再交换节点值,并不断推进 left++、right--。这种方式直观易懂,但每次都要重新从头定位,整体时间复杂度达到 O(k²),不适合区间较大的情况。
3. 一次遍历,原地反转指针(官方最佳)
官方推荐和面试官最欣赏的是只用一次遍历、原地反转指针的方案。
最佳解法思路
找到反转区间边界节点
用指针遍历链表直到第 left-1 个节点(记为 pre),和 left 节点(记为 start)。
原地反转 [left, right] 区间指针
每次将当前节点 cur 的 next 指向 pre,实现链表反转。
缓存关键指针保存连接关系
- 区间前的
pre - 区间头
start(反转后变为尾) - 反转后的区间头
end - 区间后的
next
反转后接回原链表
pre->next = end
start->next = next
总结与收获
- 链表题的核心在于理解指针和前后关系,找准"断点"并连接复原
- 面试时建议用
dummy node防止left=1的特殊情况,让代码更健壮 - 这种方法只需一次遍历,空间
O(1)原地操作 - 画图、写 down 链表节点,理清区间四端的指向关系,是高效解题的关键
你只要理解"反转区间链表的四段连接",无论什么变体题型,都能轻松应对!