从生活场景理解链表反转:最重要的基础算法

为什么这道题如此重要

反转链表看似简单,却是链表操作的基石。就像建房子要先打好地基,做复杂的链表操作前必须深刻理解反转原理。无数高频面试题都建立在这个基础之上:K个一组反转链表、判断回文链表、链表重排序等等。真正理解了反转链表,这些题目就会迎刃而解。

问题描述

LeetCode第206题"反转链表"要求:给你单链表的头节点 head,请你反转链表,并返回反转后的链表。

例如:

输入:1 → 2 → 3 → 4 → 5
输出:5 → 4 → 3 → 2 → 1

递归解法:从简单说起

递归法虽然不是最优解,但它的思路最容易理解。想象你在玩多米诺骨牌,先把所有骨牌排好,然后从最后一张开始,一张张往回推。

递归的本质

递归反转的核心思想是:

  1. 先假设子问题已经解决(后面的链表已经反转完成)
  2. 然后解决当前节点如何与已反转部分衔接的问题

就像你要完成一个大项目,不用考虑下属如何完成他们的任务,你只需要考虑如何把大家的工作整合起来。

代码实现和详解

public ListNode reverseList(ListNode head) {
// 基准情况:空链表或只有一个节点时,直接返回
if (head == null || head.next == null) {
return head;
} // 递归反转子链表,获得新的头节点
// 假设后面的链表已经反转完成,newHead指向反转后的头节点
ListNode newHead = reverseList(head.next); // 关键步骤:把当前节点接到反转后链表的末尾
// 假设当前是节点2,head.next是节点3
// head.next.next = head 就是让3指向2
head.next.next = head;
head.next = null; // 断开2原来的指向,防止形成环 return newHead;
}

迭代解法:追求空间最优

迭代法虽然理解起来较难,但它是空间复杂度最优的解法。让我们通过一个生活场景来深入理解。

通过生活场景理解迭代

想象你是一个体操教练,正在教一排学生做"后滚翻"。每个学生原本都面向前方,你要让他们一个接一个地转身。关键是:每处理一个学生时,要确保:

  1. 这个学生不会摔倒(保存next指针)
  2. 他能拉住前一个学生的手(指向prev)
  3. 准备好扶住下一个学生(移动指针)

代码实现和图解

public ListNode reverseList(ListNode head) {
ListNode prev = null; // 已翻转部分的头节点
ListNode curr = head; // 当前正在处理的节点 while (curr != null) {
// 第1步:记住下一个学生,以免等下找不到他
ListNode nextTemp = curr.next; // 第2步:让当前学生转身(改变指针指向)
curr.next = prev; // 第3步:教练和助教往后移动一位
prev = curr; // prev是"助教",扶着已完成转身的学生
curr = nextTemp; // curr是"教练",去帮助下一个学生
} return prev; // prev指向最后一个处理的节点,即新的头节点
}

迭代法的过程图解

以1→2→3→4→5为例:

初始状态:
prev = null, curr = 1
null ← 1 → 2 → 3 → 4 → 5 第一次迭代后:
prev = 1, curr = 2
null ← 1 2 → 3 → 4 → 5 第二次迭代后:
prev = 2, curr = 3
null ← 1 ← 2 3 → 4 → 5 最终状态:
null ← 1 ← 2 ← 3 ← 4 ← 5

深入理解的关键点

1. 指针操作的本质

每次操作都是在改变一个节点的"指向"。就像改变一个人的视线方向,原本看着前方,现在要回头看。

2. 迭代法的不变量

在任何时刻:

  • prev指向的是已完成反转的部分
  • curr指向正在处理的节点
  • nextTemp保存着待处理的部分

3. 为什么需要三个指针

  • prev:没有它,就不知道往哪里指
  • curr:没有它,就不知道现在处理谁
  • nextTemp:没有它,就会断链找不到后续节点

实战应用

这个基础算法在很多场景中都有应用:

  1. 需要倒序处理链表时
  2. 需要判断链表是否回文时
  3. 需要按组反转链表时
  4. 需要重排链表时

小结

掌握链表反转需要:

  1. 理解递归和迭代两种思路的本质
  2. 深入理解指针操作的含义
  3. 反复练习直至形成肌肉记忆
  4. 学会用生活场景类比,加深理解

建议:每天默写一遍这道题,直到闭着眼睛也能写对。因为它是链表操作中最基础也是最关键的操作,掌握了它,其他链表问题都会变得容易很多!


作者:忍者算法

公众号:忍者算法

我准备了一份刷题清单,以及这些题目的详细题解,覆盖了绝大部分常见面试题。我可以很负责任地说,只要你把这些题真正掌握了,80%的算法面试都能遇到相似题目。公众号回复【刷题清单】获取~

【忍者算法】从生活场景理解链表反转:最重要的基础算法|LeetCode第206题 反转链表的更多相关文章

  1. 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II

    [算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...

  2. 【python】Leetcode每日一题-反转链表 II

    [python]Leetcode每日一题-反转链表 II [题目描述] 给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 ...

  3. 【python】Leetcode每日一题-旋转链表

    [python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...

  4. Leetcode 206题 反转链表(Reverse Linked List)Java语言求解

    题目描述: 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 迭代解 ...

  5. Leetcode(206)-反转链表

    反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 思路:反转链表很简 ...

  6. leetcode每日一题——反转整数

    题目: 反转整数 难度: 简单 描述: 给定一个 32 位有符号整数,将整数中的数字进行反转. 解法: class Solution { public int reverse(int x) { //i ...

  7. [Leetcode] 第148题 排序链表

    一.题目描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示 ...

  8. 【算法】342- JavaScript常用基础算法

    一个算法只是一个把确定的数据结构的输入转化为一个确定的数据结构的输出的function.算法内在的逻辑决定了如何转换. 基础算法 一.排序 1.冒泡排序 //冒泡排序function bubbleSo ...

  9. LeetCode 上最难的链表算法题,没有之一!

    题目来源于 LeetCode 第 23 号问题:合并 K 个排序链表. 该题在 LeetCode 官网上有关于链表的问题中标注为最难的一道题目:难度为 Hard ,通过率在链表 Hard 级别目前最低 ...

  10. 关于dijkstra算法的一点理解

    最近在准备ccf,各种补算法,图的算法基本差不多看了一遍.今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的.弄了一个晚自习,先看书大致明白了原理,就根据书上的 ...

随机推荐

  1. 用OpenResty搭建高性能服务端

    相关链接:https://github.com/openresty/lua-nginx-module OpenResty 简介 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web ...

  2. AtCoder Beginner Contest 295

    Three Days Ago 我们定义一个只由数字构成的字符串中的字符能够被重排成相同的两份,我们称这个字符串是个好字符串,比如12341234 现在给定一个字符串\(S\),找出所有的\([l,r] ...

  3. Linux中touch、mkdir与vi的区别

    mkdir: 建立一个空目录 touch: 建立一个空文档,但是不进入编辑模式 vi:        建立一个空文档,进入编辑模式

  4. 【邮件伪造】SPF与DKIM验证原理及实战解析(上)

    0x01 前言 大家好,我是VoltCary 本篇文章是系列邮件安全专题的第一篇,主要帮助大家掌握邮件安全的基础知识. 基础内容包括: SMTP协议 邮件安全验证原理与过程 SPF验证与DKIM签名验 ...

  5. 在Windows下为CodeBlocks20.3安装、配置wxWidget3.2.6

    0.前言 CodeBlocks是使用C++编写程序的一个很好的开发环境,最大的好处是它是开源的.免费的,而不仅仅是因为它具有跨平台的能力.还有一个很重要的原因是在CodeBlocks中可以使用wxWi ...

  6. python 生成小学计算练习 docx

    python3 生成二年级下计算练习,有口算,有竖式. import random import osfrom docx.shared import Pt from docx import Docum ...

  7. 【Amadeus原创】docker安装apache

    1, docker下载apache [root@it-1c2d webnav]# docker search apache [root@it-1c2d webnav]# docker pull htt ...

  8. HttpClient初步理解

    昨天做完网站项目,就立刻接到了接口的项目,遇到了httpclient,因为毕业不久,遇到这块所以特此留下理解 HttpClient介绍 概念: HTTP 协议可能是现在 Internet 上使用得最多 ...

  9. Vue3 面试题 (2023-09-26更新)

    Vue3 对比 Vue2 做了那些改进? 1. 响应式系统 vue2 中使用的 Object.defineProperty 实现的响应式,劫持整个对象,递归遍历所有属性,给每个属性添加 getter ...

  10. 【Git】Gie基础操作学习笔记01

    获取项目信息 remote可以看做是一个人的电脑,假设有十个人合作,那么就有10个remote对象.为了方便大家同步,我们创建一个叫做origin的remote,大家都和这个origin同步,那么大家 ...