链表区间反转实战
链表操作最考验指针手感,也是数据结构面试中的高频考点。从基础的全链表反转,到进阶的区间反转,层层递进。本文以 LeetCode 92 为例,拆解如何用最基础的递归工具解决复杂的区间问题。
基础:反转前 n 个节点
在攻克区间反转之前,我们先实现一个核心工具函数:反转链表的前 n 个节点。这是解题的基石。
1. 函数定义与逻辑
我们需要一个递归函数 reverseN,它接收头节点和整数 n,返回反转后的新头节点。剩余未反转的节点保持原顺序。
递归的核心在于分解子问题 + 终止条件 + 回溯调整指针:
- 终止条件:当
n == 1时,说明已经到达待反转区间的最后一个节点,直接返回当前节点; - 递归调用:记录当前节点的下一个节点为
tail,递归处理head.next开头的n-1个节点; - 回溯调整:递归返回后,将当前头节点指向
tail的后继,再将tail指向当前头节点,完成局部反转。
这里有个细节要注意:tail 保存了当前节点的直接后继,它是回溯时连接后续链表的桥梁。如果没存好,后面的节点就断开了。
2. 代码实现(C++)
// 链表节点定义
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
// 核心函数:反转链表前 n 个节点(递归实现)
ListNode* reverseN(ListNode* head, int n) {
// 终止条件:n=1,到达待反转的最后一个节点
if (n == 1) {
return head;
}
// 记录当前节点的下一个节点(待反转的子链表头)
ListNode* tail = head->next;
ListNode* newHead = (head->next, n - );
head->next = tail->next;
tail->next = head;
newHead;
}


