跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

详解二叉树展开为链表:从递归到 O(1) 空间优化

介绍 LeetCode 114 题‘将二叉树展开为链表’的解法。通过递归先序遍历,利用全局指针记录链表尾部,并在递归前备份右子节点以防止结构丢失,实现原地展开。该方法直观易懂,但空间复杂度为 O(N)。

机器人发布于 2026/3/21更新于 2026/9/970 浏览
详解二叉树展开为链表:从递归到 O(1) 空间优化

详解二叉树展开为链表:从递归到 O(1) 空间优化

在二叉树的算法面试题中,'Flatten Binary Tree to Linked List' (将二叉树展开为链表) 是一道非常经典的题目(LeetCode 114)。它不仅考察我们对树遍历的理解,更考察我们在改变树结构时对指针的掌控能力。

本文将基于三种不同的思路——递归先序遍历、迭代栈模拟以及空间复杂度 O(1) 的原地变换进行思考。

题目核心目标

给定一个二叉树的根节点 root,我们需要将其展开为一个单链表:

  1. 展开后的链表顺序应与二叉树的先序遍历(根 → 左 → 右)顺序一致。
  2. 单链表使用 TreeNode 的 right 指针构建,所有节点的 left 指针必须设为 null。
  3. 原地修改,不能创建新的节点。

方法一:递归先序遍历 (直观解法)

最符合直觉的方法是直接按照先序遍历的逻辑进行递归。但是,这道题的难点在于:我们在遍历的同时正在破坏原本的树结构。

如果我们直接修改当前节点的 right 指针,原本的右子树就会丢失。为了解决这个问题,我们需要在修改指针前对右子节点进行备份。

代码实现
class Solution {
    // 全局指针,始终指向当前已处理链表的最后一个节点
    private TreeNode prev = null;

    public void flatten(TreeNode root) {
        if (root == null) return;
        preorder(root);
    }

    private void preorder(TreeNode node) {
        if (node == null) return;

        // 1. 链接操作:如果有前驱节点,将其右指针指向当前节点,左指针置空
        if (prev != null) {
            prev.left = null;
            prev.right = node;
        }

        // 2. 指针推进:当前节点成为新的链表尾部
        prev = node;

        // 3. 关键备份:暂存右子节点
        // 原因:下一步递归左子树时,prev (即当前 node) 的 right 指针会被修改指向左子节点
        // 若不备份,原右子树的引用将丢失
        TreeNode right = node.right;

        preorder(node.left);
        preorder(right);
    }
}

该方法逻辑清晰,但需要 O(N) 的递归栈空间。后续可探讨如何进一步优化至 O(1) 空间复杂度。

目录

  1. 详解二叉树展开为链表:从递归到 O(1) 空间优化
  2. 题目核心目标
  3. 方法一:递归先序遍历 (直观解法)
  4. 代码实现

更多推荐文章

查看全部
  • 把 AI 数学公式稳妥复制到 Word 的几种办法
  • FLUX.1-dev与Stable Diffusion 对比评测:图像质量与生成速度
  • 机器人通讯总线选型:CAN/FD、高速 485 与 EtherCAT 深度对比
  • 腾讯混元 7B 开源:256K 上下文与数学推理升级
  • GitHub Copilot 使用体验与功能场景分析
  • IntelliJ IDEA 中 Java 文件图标显示为咖啡杯的解决方法
  • GitHub Copilot 学生认证指南:合规申请与常见问题解析
  • Ansible 批量部署 Nginx 实战
  • 鸿蒙电商购物车全栈项目:用户管理、商品列表与购物车实现
  • OpenClaw 登顶 GitHub 星标榜首,单人开发重塑 AI 代理格局
  • OpenClaw + LMStudio + 飞书:搭建本地离线 AI 助手
  • STL 红黑树(RB-tree)原理与插入操作实现详解
  • Node.js 安装指南(Windows 版本)
  • SCons:Python 驱动的智能跨平台构建系统
  • 使用 Video.js 和 WebRTC 构建视频会议原型
  • 前端大数据导出优化:解决 Chrome 内存崩溃的实战方案
  • 位运算实战:两整数之和与只出现一次的数字
  • 昇腾 NPU 部署 Llama 2 模型:性能测试与优化实践
  • Python 驱动浏览器自动化:Playwright 与 AI 集成实战
  • 国内主流 AI 大模型架构及应用场景深度分析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online