1. 链表反转问题概述
链表反转是数据结构与算法中最经典的面试题之一,也是考察程序员对指针操作理解深度的绝佳案例。这道题看似简单,却能区分出不同水平的候选人。在实际面试中,超过60%的候选人能写出基本解法,但只有不到30%能同时给出递归和迭代两种解法的完整实现。
链表反转的核心在于改变节点间的指针方向。想象你有一串珍珠项链,每颗珍珠都连着下一颗。反转链表就像把这串项链拆开,然后从另一端重新串起来。这个过程中,最关键的是不能丢失任何一颗珍珠(节点),同时要确保每颗珍珠都正确地指向它的新邻居。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 递归解法深度解析
2.1 递归思路拆解
递归解法遵循"分而治之"的思想,将大问题分解为小问题。对于链表反转,可以这样思考:如果我能反转从第二个节点开始的子链表,那么只需要把第一个节点放到反转后的子链表的末尾即可。
具体步骤分解:
- 递归到底:一直递归到链表最后一个节点,这个节点就是反转后新链表的头节点
- 回溯反转:在每一层递归返回时,将当前节点的下一个节点的next指针指向自己
- 断开原链:将当前节点的next置为nullptr,防止形成环
关键提示:递归终止条件必须同时处理空链表(head==nullptr)和单节点链表(head->next==nullptr)两种情况,这是很多面试者容易遗漏的边界条件。
2.2 递归复杂度分析
时间复杂度O(n):
- 递归深度与链表长度n成正比
- 每层递归只进行常数时间操作(指针修改)
空间复杂度O(n):
- 递归调用栈的深度等于链表长度
- 对于长链表可能导致栈溢出,这是递归解法的主要限制
2.3 递归代码实现细节
cpp复制ListNode* reverseList(ListNode* head) {
// 递归终止条件:空链表或单节点链表
if(!head || !head->next) {
return head;
}
// 递归反转子链表
ListNode* newHead = reverseList(head->next);
// 关键反转操作
head->next->next = head; // 让下一个节点指向自己
head->nex
