翻转等价二叉树-LeetCode
951. 翻转等价二叉树 - Flip Equivalent Binary Trees
🎯 问题描述(来源于LeetCode)
描述:
给定两棵二叉树的根节点 root1 和 root2,判断它们是否翻转等价。
定义:如果可以通过执行若干次“翻转”操作(交换任意节点的左右子节点)使一棵树变成另一棵树,则两棵树翻转等价。
说明:
- “翻转”操作可以应用在任意节点上,次数不限。
- 空树与自身翻转等价。
示例:
- 示例 1:
1 | 输入: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = [1,3,2,null,6,4,5,null,null,null,null,8,7] |
- 示例 2:
1 | 输入: root1 = [], root2 = [] |
- 示例 3:
1 | 输入: root1 = [], root2 = [1] |
💻 解题思路
思路1:递归 + 分情况讨论(翻转 / 不翻转)
算法步骤
-
处理空节点:
- 如果
root1或root2有一个为None,则只有两者同时为None时才返回True,否则False。
- 如果
-
比较根节点值:
- 如果两棵树根节点值不同,直接返回
False(无法通过翻转使值相等)。
- 如果两棵树根节点值不同,直接返回
-
递归检查子树(两种可能性):
- 不翻转:左子树与左子树比较,右子树与右子树比较。
即flipEquiv(root1.left, root2.left) and flipEquiv(root1.right, root2.right) - 翻转:左子树与右子树比较,右子树与左子树比较。
即flipEquiv(root1.left, root2.right) and flipEquiv(root1.right, root2.left)
- 不翻转:左子树与左子树比较,右子树与右子树比较。
-
返回结果:
- 只要两种检查中至少有一种成立,则两棵树翻转等价。
思路1:代码实现
1 | # Definition for a binary tree node. |
思路1:📊 性能分析
复杂度验证
- 时间复杂度:,最坏情况下(两棵树相同或翻转等价时)每个节点被访问一次。实际递归会探索两条路径,但由于剪枝(值不等时立即返回
False),整体复杂度为 , 为节点数较少的树的节点数。 - 空间复杂度:,其中 为树的高度。递归调用栈的深度最大为树高,最坏情况(链状)为 。
思考
- 本题的核心在于灵活处理翻转:不需要真正翻转树,只需在递归时交叉比较子树即可。
- 注意代码中
flip和no_flip都先判断root1.val == root2.val,实际上可以提前判断,避免重复比较。简洁写法可以写成:1
2
3return (root1.val == root2.val and
((self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right)) or
(self.flipEquiv(root1.left, root2.right) and self.flipEquiv(root1.right, root2.left)))) - 本题也可用广搜 + 队列迭代检查,但递归写法最直观。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






