LeetCode 226. 翻转二叉树(多种解法详解)

题目描述

LeetCode 226. 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

text

复制代码
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

text

复制代码
输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

text

复制代码
输入:root = []
输出:[]

解题思路

翻转二叉树的核心思想是:对于每个节点,交换它的左右子树,然后递归或迭代地处理所有子节点。这道题虽然简单,但考察了对二叉树遍历的理解,也是很多面试的"热身题"。


解法一:递归(DFS,前序遍历)

思路

最直观的解法。对于当前节点 root

  1. 交换它的左右子节点

  2. 递归翻转左子树

  3. 递归翻转右子树

这本质上是前序遍历的应用。

代码实现

java

复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归终止条件:空节点直接返回
        if (root == null) {
            return null;
        }
        
        // 交换左右子节点
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        
        // 递归翻转左右子树
        invertTree(root.left);
        invertTree(root.right);
        
        return root;
    }
}

更简洁的写法:

java

复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        
        TreeNode left = invertTree(root.left);
        TreeNode right = invertTree(root.right);
        
        root.left = right;
        root.right = left;
        
        return root;
    }
}

复杂度分析

  • 时间复杂度:O(n),n 为节点数,每个节点访问一次

  • 空间复杂度:O(h),h 为树的高度,递归栈的深度


解法二:递归(后序遍历)

思路

也可以用后序遍历:先递归翻转左右子树,然后再交换当前节点的左右子节点。

代码实现

java

复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        
        // 后序遍历:先处理子树
        invertTree(root.left);
        invertTree(root.right);
        
        // 再交换当前节点的左右子节点
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        
        return root;
    }
}

前序 vs 后序

遍历方式 区别
前序遍历 先交换当前节点,再处理子节点
后序遍历 先处理子节点,再交换当前节点

两者都能正确完成翻转,前序更符合"由上到下"的直觉,后序则体现了"由下到上"的思想。


解法三:迭代(BFS,层序遍历)

思路

使用队列进行层序遍历,逐层处理每个节点:将当前节点的左右子节点交换,然后将非空的子节点加入队列继续处理。

代码实现

java

复制代码
import java.util.LinkedList;
import java.util.Queue;

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        
        while (!queue.isEmpty()) {
            TreeNode current = queue.poll();
            
            // 交换当前节点的左右子节点
            TreeNode temp = current.left;
            current.left = current.right;
            current.right = temp;
            
            // 将子节点加入队列
            if (current.left != null) {
                queue.offer(current.left);
            }
            if (current.right != null) {
                queue.offer(current.right);
            }
        }
        
        return root;
    }
}

复杂度分析

  • 时间复杂度:O(n)

  • 空间复杂度:O(n),队列在最坏情况下存储 n/2 个节点


解法四:迭代(DFS,前序遍历)

思路

使用栈模拟递归的前序遍历过程。

代码实现

java

复制代码
import java.util.Stack;

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        
        while (!stack.isEmpty()) {
            TreeNode current = stack.pop();
            
            // 交换左右子节点
            TreeNode temp = current.left;
            current.left = current.right;
            current.right = temp;
            
            // 先压右再压左,确保左子树先被处理(模拟前序遍历)
            if (current.right != null) {
                stack.push(current.right);
            }
            if (current.left != null) {
                stack.push(current.left);
            }
        }
        
        return root;
    }
}

复杂度分析

  • 时间复杂度:O(n)

  • 空间复杂度:O(h),栈的深度


解法对比

解法 空间复杂度 优点 适用场景
递归(前序) O(h) 代码简洁,最直观 默认首选
递归(后序) O(h) 体现后序思想 学习意义
BFS 迭代 O(n) 避免递归栈溢出 树很深时
DFS 迭代 O(h) 空间优于 BFS 树很深时

推荐:日常刷题用递归最简洁,面试中如果要求非递归可以用迭代版本。


经典梗:Max Howell 的故事

这道题之所以出名,很大程度是因为 2015 年 Homebrew 作者 Max Howell 在 Twitter 上的吐槽:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a whiteboard so fuck off.

大意:Google 说"我们 90% 的工程师都用你写的软件,但你连翻转二叉树都写不出来,滚蛋吧。"

这个故事让这道题成为面试领域的"传奇",也提醒我们:不要因为基础题简单就忽视它,大神也会栽跟头 😂


扩展思考

  1. 对称二叉树(LeetCode 101):翻转后的树是否等于原树?

  2. 二叉树的镜像:翻转二叉树在图形学中也有应用

  3. N 叉树的翻转:思路类似,将每个节点的子节点列表反转


总结

翻转二叉树的本质就是交换每个节点的左右子节点。无论是递归还是迭代,核心操作都是交换。

这道题看似简单,但考察了对二叉树遍历的掌握程度,也是很多公司面试的"试金石"。熟练掌握三种解法(递归、BFS、DFS),面试中就可以游刃有余。


题目链接 & 题解链接


如果这篇文章对你有帮助,欢迎点赞、收藏、关注!更多 LeetCode HOT 100 题解持续更新中~

相关推荐
徐小夕1 小时前
表格、文档、甘特、大屏、表单一站打通:pxcharts超级表格4.0正式上线!
前端·算法·github
TechLee2 小时前
跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通
java·后端·算法
月华路4 小时前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
万法若空4 小时前
排列组合恒等式
c++·算法
Nil2084 小时前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
一直C4 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
淡海水4 小时前
04-02-哈希-Dictionary-TKey-TValue-上-核心数据结构
数据结构·算法·c#·哈希算法·编译·字典·dictionary
戴西软件4 小时前
国内有哪些数据轻量化格式转换软件?
数据库·算法·安全·信息可视化·自动化·rpa
老洋葱Mr_Onion5 小时前
【C++】CSP-J初赛模拟卷七错题整理(作者自用)
c++·算法·深度优先
Nil2085 小时前
leetcode 114二叉树展开为链表
leetcode·链表·深度优先