跳到正文
第 226 题简单

翻转二叉树

Invert Binary Tree

把二叉树的每个节点的左右子树互换,返回翻转后的根节点。

在力扣中练习

题目描述

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

 

示例 1:

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

示例 2:

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

 

提示:

  • 树中节点数目范围在 [0, 100] 内
  • -100 <= Node.val <= 100

解题思路

主解法

递归 · 先交换再下探

当前节点换孩子,左右子树各自翻转

翻转一棵树,可以拆成三件事:交换当前节点的左右孩子、翻转左子树、翻转右子树。三件事互不影响,所以先交换还是先递归都可以。

分步图解

空节点直接返回;从根开始,先交换左右孩子,再递归处理两棵子树。

交换每个节点的左右孩子左子树 · 右子树
5382479
当前根
[ ]
1 / 3
根节点的两个孩子先对调,随后递归进入新的左子树 8。

递归到空节点时返回。交换后原来的左子树变成右子树,但节点本身和它的值没有变,只是左右关系对调。

分步图解

交换 5 的左右孩子:现在左边是 8,右边是 3。

交换每个节点的左右孩子左子树 · 右子树
5已交换382479
当前根
root=5
1 / 3
每个非叶节点都执行一次交换,整棵树因此左右镜像。

自拟树是一棵三层满二叉树,交换根之后递归顺序会先进入原来的右子树 8;画面上节点位置会左右移动,这是交换孩子后的真实布局,不是节点值变了。

时间 O(n),每个节点访问一次;空间 O(h) 递归栈。

时间 O(n)空间 O(h) 递归栈

易错点

  • 只交换根的孩子:子树内部没有翻转,结果只是左右两棵子树整体换位。
  • 交换值而不是交换孩子:如果节点带额外字段或需要保持节点身份,会出错。
  • 空树没有处理:递归进入空指针。
对照解法

层序 · 队列

每个出队节点都交换孩子,再把孩子入队

同样 O(n),但需要 O(宽度) 队列;递归版更短,队列版避免深递归。

用队列遍历每个节点:出队时交换它的左右孩子,然后把(交换后的)左右孩子入队。因为每个节点都会被处理一次,整棵树自然完成镜像。

与递归版相比,它不依赖调用栈,适合树很深的情况;代价是队列可能同时保存一整层节点。

注意入队时用的是交换后的孩子,但两个孩子都会被入队,所以先入左还是先入右不影响最终结果。

  1. 1根节点入队。
  2. 2出队一个节点,交换它的左右孩子。
  3. 3把两个孩子入队。
  4. 4队列空时返回根。
时间 O(n)空间 O(宽度)

易错点

  • 交换后只入队一个孩子:另一棵子树漏翻。
  • 空树直接入队:队列里出现空指针。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入root = [5,3,8,2,4,7,9]

空节点直接返回;从根开始,先交换左右孩子,再递归处理两棵子树。

交换每个节点的左右孩子左子树 · 右子树
5382479
当前根
[ ]
1 / 3
查看 C++ 代码

延伸阅读

  • 翻转、镜像、对称判断都围绕“左右互换”这一个操作,可以先想清楚交换发生在递归前还是递归后。
  • 交换左右孩子会改变中序遍历的结果;如果题目还要求保持 BST 性质,需要额外小心。