LeetCode 二叉树双王炸!二叉树展开为链表 + 前序 + 中序还原二叉树|小白递归一把过

目录

一、二叉树展开为链表(前序遍历秒杀)

[🎯 题目要求](#🎯 题目要求)

[💡 超简单思路](#💡 超简单思路)

[✅ 完整解题代码](#✅ 完整解题代码)

[📝 小白通俗解析](#📝 小白通俗解析)

二、从前序与中序遍历序列构造二叉树(递归分治经典)

[🎯 题目要求](#🎯 题目要求)

[💡 核心思路(小白秒懂)](#💡 核心思路(小白秒懂))

[✅ 完整解题代码](#✅ 完整解题代码)

[📝 小白通俗解析](#📝 小白通俗解析)

[🎉 两道题终极口诀(秒记)](#🎉 两道题终极口诀(秒记))

二叉树展开为链表

[前序 + 中序还原二叉树](#前序 + 中序还原二叉树)

[🌟 总结](#🌟 总结)


一、二叉树展开为链表(前序遍历秒杀)

🎯 题目要求

给定一个二叉树,将它展开成一个 **"单链表"**,要求:

  1. 展开后的链表使用原树节点
  2. 所有节点的左孩子为 null
  3. 右孩子指向下一个节点
  4. 顺序与前序遍历一致

💡 超简单思路

  1. 前序遍历二叉树,把所有节点按顺序存到集合里
  2. 遍历集合,把前一个节点的左孩子置空右孩子指向后一个节点
  3. 链表拼接完成!

✅ 完整解题代码

java

运行

复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 存储前序遍历的所有节点
    private List<TreeNode> list = new ArrayList<>();

    public void flatten(TreeNode root) {
        if(root == null) return;
        // 1. 前序遍历收集所有节点
        travle(root);

        // 2. 拼接成单向链表
        for(int i = 0; i < list.size() - 1; i++){
            TreeNode pre = list.get(i);
            TreeNode cur = list.get(i+1);
            // 左孩子置空
            pre.left = null;
            // 右孩子指向下一个节点
            pre.right = cur;
        }
    }

    // 前序遍历:根 → 左 → 右
    public void travle(TreeNode node) {
        if(node == null) return;
        // 先收集当前节点
        list.add(node);
        // 遍历左子树
        travle(node.left);
        // 遍历右子树
        travle(node.right);
    }
}

📝 小白通俗解析

  • 前序遍历 = 根节点先加入,再遍历左右子树
  • 用集合保存所有节点后,直接按顺序拼接
  • 左边全部清空,右边连成一条线,就是题目要求的链表
  • 代码短短几行,逻辑一目了然,面试写这个最快最稳!

二、从前序与中序遍历序列构造二叉树(递归分治经典)

🎯 题目要求

给定二叉树的前序遍历中序遍历数组,还原出这棵二叉树。

💡 核心思路(小白秒懂)

  1. 前序遍历第一个节点 = 整棵树的根节点
  2. 中序遍历 中找到根节点位置
    • 根节点左边 = 左子树
    • 根节点右边 = 右子树
  3. 递归分治,不断切割数组,重复找根→建节点→分左右子树
  4. 用 Map 记录中序遍历值与下标,快速找根节点位置

✅ 完整解题代码

java

运行

复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 记录中序数组:值 → 下标,快速定位根节点
    private Map<Integer, Integer> map = new HashMap<>();

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 把中序数组存入map
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        // 递归建树(左闭右开区间)
        return find(preorder, 0, preorder.length,
                    inorder, 0, inorder.length);
    }

    // 递归分治建树
    public TreeNode find(int[] preorder, int preorderBegin, int preorderEnd,
                         int[] inorder, int inorderBegin, int inorderEnd){
        // 递归终止条件:区间无效
        if(preorderBegin >= preorderEnd || inorderBegin >= inorderEnd){
            return null;
        }

        // 前序第一个节点 = 根节点
        int rootVal = preorder[preorderBegin];
        // 找到根节点在中序数组中的位置
        int rootIndex = map.get(rootVal);
        TreeNode root = new TreeNode(rootVal);

        // 左子树节点个数
        int leftSize = rootIndex - inorderBegin;

        // 递归构建左子树
        root.left = find(preorder, preorderBegin + 1, preorderBegin + 1 + leftSize,
                          inorder, inorderBegin, rootIndex);

        // 递归构建右子树
        root.right = find(preorder, preorderBegin + 1 + leftSize, preorderEnd,
                           inorder, rootIndex + 1, inorderEnd);

        return root;
    }
}

📝 小白通俗解析

  • 前序找根中序分左右
  • 用 Map 快速定位根节点,避免每次遍历数组
  • 按区间切割数组,递归建左右子树
  • 标准分治递归思想,代码规范,面试必背模板

🎉 两道题终极口诀(秒记)

二叉树展开为链表

前序遍历存节点,循环拼接右指针,左边全部置为空

前序 + 中序还原二叉树

前序找根,中序分左右;递归切割,分治建树


🌟 总结

这两道题是二叉树最经典、最高频 的面试题!一道考察前序遍历 + 链表拼接 ,一道考察递归分治 + 还原二叉树,都是刷题必掌握核心知识点。

代码简洁、思路清晰,学会这两道,二叉树递归 / 遍历题型直接通关!

相关推荐
三品吉他手会点灯1 分钟前
C语言学习笔记 - 43.运算符与表达式 - 运算符1 - 运算符的分类和简单介绍
c语言·笔记·学习·算法
VkN2X2X4b12 分钟前
算法复杂度的实验验证与误差分析的技术8
算法
其利天下技术21 分钟前
风扇灯无刷电机自适应算法实战指南
算法·cocos2d·无刷电机自适应算法·bldc驱动自适应算法·其利无刷电机驱动算法
8Qi827 分钟前
LeetCode 494:目标和(Target Sum)—— 题解 ✅
算法·leetcode·职场和发展·动态规划·01背包
hujinyuan201601 小时前
2026年3月 中国电子学会青少年软件编程(Python)三级考试试卷 真题及答案
java·python·算法
froyoisle1 小时前
CSP-J 历年复赛 T1 及解析(2019~2025)
数据结构·c++·算法·csp-j·csp·算法竞赛·信息学
珊瑚里的鱼2 小时前
【动态规划】打家劫舍Ⅱ
算法·动态规划
chao1898442 小时前
SGM(Semi-Global Matching)立体匹配算法 — C++ 实现
开发语言·c++·算法
黎阳之光2 小时前
数智赋能水厂全链路安全|黎阳之光以视频孪生技术落地供水精细化管控
人工智能·物联网·算法·安全·数字孪生
NOVAnet20232 小时前
AI 全球化部署网络瓶颈:算法模型跨地域、跨云互联核心痛点解析
算法·ai·sd-wan·专线·跨区域