在问 · 算法题解

226. 翻转二叉树

简单二叉树递归(前序交换左右子树)力扣原题 ↗

题目描述

输入二叉树的根节点 root。把树左右镜像翻转:每个节点的左子树和右子树互换。

返回翻转后的根节点。空树返回 null。树以层序数组表示。

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

解释:每一层的节点顺序都左右颠倒了。

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

解释:根的两个孩子 1 和 3 互换位置。

示例 3
输入:root = []
输出:[]

解释:空树翻转后仍为空。

数据范围

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

解题思路:递归(前序交换左右子树)

先交换当前节点的左右孩子,再递归翻转交换后的两棵子树。

为什么正确

调用返回时,当前子树中的每个节点都完成左右交换。

复杂度分析

时间 O(n),递归栈 O(h);h 为树高,最坏可为 n;Python 递归受解释器递归深度限制,深链树应改用显式栈。

易错点

翻转要处理每个节点,不能只交换根节点的两个孩子。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def invertTree(self, root):
        if root is None:
            return None
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

载入编辑器,自己跑一遍 →

其他解法

翻转只要求每个结点都交换一次左右孩子,与访问顺序无关。递归借用调用栈做深度优先遍历,空间取决于树高;BFS 用队列逐层遍历,空间取决于树宽。

解法 2:广度优先搜索(迭代) 时间 O(n),空间 O(n)

用队列按层遍历所有结点。每取出一个结点,就交换它的左右孩子,再把非空的孩子放入队列。每个结点都恰好被交换一次,遍历结束后整棵树就翻转了。

没有递归,树退化成链时也不会栈溢出。需要显式维护队列,代码比递归长;队列大小取决于最宽的一层。

from collections import deque
from typing import Optional

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            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

二叉树 专题的其他题目

查看 二叉树 全部题目 →