226. 翻转二叉树 (Easy)
专题归类: 05-二叉树 LeetCode 链接: https://leetcode.cn/problems/invert-binary-tree/
在线做题: 写 Python 代码并运行 · Java 跳转 LeetCode
题目描述
给你一棵二叉树的根节点 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
题目详细分析
- 数据范围含义: 节点数最多 100,值范围 [-100, 100],非常小,递归绝不会栈溢出。
- 输入输出特征: 输入一个树的根节点,输出翻转后同一个树的根节点(原地修改,非新建树)。
- 边界条件: 空树直接返回 None;单节点无需翻转。
- 核心约束: 必须对每个节点都执行左右子树交换,叶子节点交换两个 None 不影响。
- 隐藏条件: 这题的出名是因为 Homebrew 作者在 Google 面试时没写出来。本质上考察的是二叉树递归的基础操作。
小白版直白理解
就像照镜子——你举起左手,镜子里的人举起右手。翻转二叉树就是给整棵树照一次镜子:每个节点的左边变成右边,右边变成左边。从最底下的叶子开始,一层一层往上交换,整棵树就被镜像翻转了。
解题思路
思路一:前序递归(推荐)
核心思想: 先交换当前节点的左右孩子,再递归地去翻转左右子树。
为什么用前序? 前序位置是在「进入一个节点后、处理子树之前」执行操作。对于翻转问题,先交换当前节点的左右孩子,然后递归处理它们——这非常符合直觉:先交换,再处理。
def invertTree(root):
if not root:
return None
# 前序位置:先交换当前节点的左右子树
root.left, root.right = root.right, root.left
# 递归翻转左右子树
invertTree(root.left)
invertTree(root.right)
return root思路二:后序递归
核心思想: 先递归翻转左右子树,然后再交换当前节点的左右孩子。
为什么后序也可以? 后序是先处理完子树再回到当前节点。你先确保左右子树各自已经被翻转好了,再交换它们——左右子树内部已经镜像,交换后整棵树就镜像了。
def invertTree(root):
if not root:
return None
# 先递归翻转左右子树
left = invertTree(root.left)
right = invertTree(root.right)
# 后序位置:交换翻转好的左右子树
root.left = right
root.right = left
return root思路三:BFS 迭代
用队列层序遍历,每遇到一个节点就交换它的左右孩子。
适用场景: 不想用递归时,用 BFS 迭代同样可以完成任务。
from collections import deque
def invertTree(root):
if not root:
return None
q = deque([root])
while q:
node = q.popleft()
# 交换当前节点的左右孩子
node.left, node.right = node.right, node.left
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return root易错点
- 交换的是子树,不是值: 需要交换
root.left和root.right(让整个子树换边),而不是交换root.left.val和root.right.val。 - 前序递归不需要保存返回值:
invertTree(root.left)的返回值不需要赋值给任何变量,因为翻转是在原地进行的。 - 后序递归的赋值顺序: 如果先把左子树的翻转结果赋给 root.left,再处理右子树,要注意 root.left 已经被修改了。正确做法:先保存左右,或者后序时在交换时用临时变量。
- 空节点处理:
if not root: return None是必须的 base case。
框架提炼
二叉树递归修改结构模板: 无论是翻转、展开、还是重建,都可以用「前序做操作+递归处理子树」或「递归处理子树+后序做操作」两种模式。
前序模式:操作当前节点 → 递归左右子树
后序模式:递归左右子树 → 操作当前节点
关键区别:前序是「自上而下」的指令式操作,后序是「自下而上」的归并式操作。
关联题目
- 101-对称二叉树 — 翻转是让左右不对称,对称是检查左右是否镜像,两者是逆向思维。
- 104-二叉树的最大深度 — 同为二叉树基础递归题,递归思维模式一致。
- 114-二叉树展开为链表 — 同样是原地修改树结构,使用了后序 + prev 指针技巧。