#206 链表指针 简单

反转链表

在 LeetCode 上查看 ↗

🎧 语音讲解

开车或通勤时可听,跟着思路走一遍

速度

📋 题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

💭 模拟答题者思考

1. 直观想法:我需要把每个节点的 next 指针反过来指向前一个节点。

2. 关键问题:改了 cur.next 之后,我就找不到原来的下一个节点了——所以在改之前必须用 nxt 保存。

3. 初始状态:第 0 个位置是 null(pre = None),第 1 个是 head(cur = head)。

4. 循环结束后 pre 就指向了新的头节点(原链表的尾)。

🧠 变量语义(先读这三句再编码)

变量类型语义(三句法)
preListNode*定义:已反转部分的头节点
维护:始终指向已反转链表的首节点
更新:每轮 pre = cur(cur 被接入反转链表头部)
curListNode*定义:当前正在处理的节点
维护:指向原链表中下一个待反转的节点
更新:每轮 cur = nxt(移到下一个)
nxtListNode*定义:cur 的原后继(改指针前先保存,防断链)
维护:每轮保存 cur.next
更新:nxt = cur.next(在 cur.next 被改写之前)

⌨️ 落码步骤

1. pre = None, cur = head

2. 循环:nxt = cur.next(保存后继,防断链)

3. cur.next = pre(反转指针)

4. pre = cur; cur = nxt(两指针前移)

5. 返回 pre

💻 代码实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        pre = None  # 已反转部分的头节点
        cur = head  # 当前正在处理的节点

        while cur:
            nxt = cur.next  # 先保存后继,防断链
            cur.next = pre  # 反转指针
            pre = cur       # pre 前移
            cur = nxt       # cur 前移

        return pre
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;  // 已反转部分的头节点
        ListNode* cur = head;     // 当前正在处理的节点

        while (cur) {
            ListNode* nxt = cur->next;  // 先保存后继,防断链
            cur->next = pre;            // 反转指针
            pre = cur;                  // pre 前移
            cur = nxt;                  // cur 前移
        }
        return pre;
    }
};
// 时间 O(n),空间 O(1)
// 递归版:reverseList(head.next) 后 head.next.next = head; head.next = null;

📈 复杂度分析

时间复杂度 O(n)
空间复杂度 O(1)

⚠️ 常见坑

顺序!必须先 nxt = cur.next 保存,再修改 cur.next。反过来就会「断链」——丢失后续所有节点。

返回值是 pre 不是 cur:循环结束时 cur 是 None,pre 才是新头。

空链表 / 单节点:while 直接跳过,返回 pre(null 或 head),行为正确。

🔍 必测边界 Case

Case 1:空链表
head = null → 输出 null
Case 2:单节点
head = [1] → 输出 [1]