hot 206

【LeetCode 简单题】206. 反转链表:两种思路 + 代码详解

今天来拆解 LeetCode 上的经典简单题 ------206. 反转链表,这是链表操作的入门必刷题,同时也是很多面试的 "开胃菜"。本文会分享两种常用解法,从思路到代码逐一分析,帮你彻底搞懂链表反转的逻辑~

题目描述

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

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

解法一:双指针法(原地反转,空间复杂度 O (1))

这是链表反转的最优解法,不需要额外空间,直接在原链表上修改指针指向。

思路分析

核心是用两个指针跟踪节点,通过 "断链 - 反转指向 - 移动指针" 的步骤,逐步将原链表的节点反向串联。

步骤拆解:

  1. 定义两个指针:newHead(指向反转后的新链表头,初始为 nullptr)、temp(临时存储原链表的下一个节点);
  2. 遍历原链表,每次取出当前节点 head
    • 先用 temp 保存 head 的下一个节点(防止断链后找不到后续节点);
    • headnext 指向 newHead(完成当前节点的反转);
    • 移动 newHeadhead(新链表头更新为当前节点);
    • 移动 headtemp(继续遍历原链表);
  3. 遍历结束后,newHead 就是反转后的链表头。

代码实现

cpp

运行

复制代码
/**
 * Definition for singly-linked list.
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* newHead = nullptr;  // 反转后的新链表头
        ListNode* temp = nullptr;     // 临时存储原链表的下一个节点
        while (head) {
            temp = head->next;        // 保存下一个节点
            head->next = newHead;     // 当前节点指向新链表头(反转)
            newHead = head;           // 新链表头更新为当前节点
            head = temp;              // 继续遍历原链表
        }
        return newHead;
    }
};

解法二:辅助容器法(思路直观,空间复杂度 O (n))

如果对指针操作不熟悉,可以先用辅助容器暂存节点信息,再重新构建链表。这种方法思路更直观,适合新手理解。

思路分析

vector 存储原链表的所有节点值,反转容器后,基于容器中的值创建新链表。

步骤拆解:

  1. 遍历原链表,将每个节点的 val 存入 vector
  2. 反转 vector(此时容器内的值是原链表的逆序);
  3. 创建一个虚拟头节点 dummy(简化新链表的串联逻辑),遍历反转后的 vector,依次创建新节点并串联;
  4. 返回虚拟头节点的 next(即新链表的头)。

代码实现

复制代码
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        vector<int> vals;
        // 1. 存储原链表的所有节点值
        while (head) {
            vals.emplace_back(head->val);
            head = head->next;
        }
        // 2. 反转容器(值的顺序逆序)
        reverse(vals.begin(), vals.end());
        
        // 3. 基于反转后的值构建新链表
        ListNode* dummy = new ListNode(0);  // 虚拟头节点
        ListNode* cur = dummy;
        for (int val : vals) {
            cur->next = new ListNode(val);  // 创建新节点
            cur = cur->next;                // 移动指针
        }
        return dummy->next;  // 虚拟头的next是新链表头
    }
};

两种解法对比

解法 时间复杂度 空间复杂度 适用场景
双指针法 O(n) O(1) 追求空间效率,面试推荐写法
辅助容器法 O(n) O(n) 新手理解链表反转逻辑,或需保留原链表

总结

反转链表是链表操作的基础题,双指针法是必须掌握的最优解(空间 O (1)、逻辑清晰),辅助容器法则是 "退而求其次" 的直观思路。建议先理解辅助容器法的逻辑,再过渡到双指针法的指针操作~

如果你有其他解法,欢迎在评论区交流~

相关推荐
ting94520003 小时前
Humalike X Hermes 深度技术剖析:单指令注入群聊社交智能的底层架构、算法与跨 IM 平台实现
人工智能·算法·架构
豆沙沙包?3 小时前
C++~~~stack容器、queue容器、list容器(p45-P56)
c++·windows·list
Data_Journal3 小时前
用于网页抓取的 Node-unblocker
大数据·开发语言·数据库·python·scrapy
吴声子夜歌3 小时前
Java面试——算法
java·算法·面试
evans在进步3 小时前
LeetCode 64:最小路径和——Java 原地动态规划详解
java·leetcode·动态规划
豆角焖肉3 小时前
SSM 聚合项目搭建:多 Maven 模块项目
开发语言·python·pycharm
Frank_refuel3 小时前
【C++八股】面向对象
开发语言·c++
h_a_o777oah3 小时前
【图论】Tarjan 缩点:解决有向图中环的问题
c++·算法·图论·acm·强连通分量·缩点·tarjan
Tisfy3 小时前
LeetCode 1386.安排电影院座位:哈希表+位运算
算法·leetcode·散列表·题解·哈希表
青 春 记 忆3 小时前
零基础入门python20:Flask配置、扩展和蓝图拆分
python·flask·后端开发