二叉树题目:翻转等价二叉树

题目

标题和出处

标题:翻转等价二叉树

出处:951. 翻转等价二叉树

难度

4 级

题目描述

要求

对于二叉树,我们可以定义如下翻转操作:选择任意结点,然后交换其左子树和右子树。

对于两个二叉树 X 和 Y,当且仅当经过一定次数的翻转操作之后能使 X 等于 Y 时,二叉树 X 翻转等价于二叉树 Y。

给定两个二叉树的根结点 root1 \texttt{root1} root1 root2 \texttt{root2} root2,如果两个二叉树翻转等价,则返回 true \texttt{true} true,否则返回 false \texttt{false} false

示例

示例 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] \texttt{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]} 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]
输出: true \texttt{true} true
解释:我们翻转值为 1 \texttt{1} 1 3 \texttt{3} 3 以及 5 \texttt{5} 5 的三个结点。

示例 2:

输入: root1   =   [],   root2   =   [] \texttt{root1 = [], root2 = []} root1 = [], root2 = []
输出: true \texttt{true} true

示例 3:

输入: root1   =   [],   root2   =   [1] \texttt{root1 = [], root2 = [1]} root1 = [], root2 = [1]
输出: false \texttt{false} false

数据范围

  • 树中结点数目在范围 [0,   100] \texttt{[0, 100]} [0, 100]
  • 树中每个结点的值都是范围 [0,   99] \texttt{[0, 99]} [0, 99] 内的唯一值

解法

思路和算法

由于每次翻转操作只会将选定结点的左子树和右子树交换,不会改变选定结点的值,因此如果两个二叉树翻转等价,则这两个二叉树的根结点一定满足以下两种情况之一。

  1. 两个二叉树的根结点都为空,即两个二叉树都为空。

  2. 两个二叉树的根结点都不为空且两个二叉树的根结点值相同。

对于第 1 种情况,由于两个二叉树都为空,因此两个二叉树翻转等价。对于第 2 种情况,需要继续对两个二叉树的左子树和右子树判断是否满足翻转等价。

由于根结点可能不翻转或翻转,因此当两个二叉树翻转等价时,可能有以下两种情况。

  1. 根结点不翻转,则第一个二叉树的左子树和第二个二叉树的左子树翻转等价,且第一个二叉树的右子树和第二个二叉树的右子树翻转等价。

  2. 根结点翻转,则第一个二叉树的左子树和第二个二叉树的右子树翻转等价,且第一个二叉树的右子树和第二个二叉树的左子树翻转等价。

由于两个二叉树是否翻转等价取决于两个二叉树的左子树和右子树之间是否存在翻转等价的关系,因此可以使用深度优先搜索实现,整个过程是一个递归的过程。

如果两个二叉树的根结点都为空,则两个二叉树翻转等价。如果两个二叉树的根结点只有一个为空,则两个二叉树不翻转等价。这两种情况是递归的终止条件。

对于其余情况,首先判断两个二叉树的根结点值是否相同,然后执行递归。

  1. 如果两个二叉树的根结点值不同,则两个二叉树不翻转等价。

  2. 如果两个二叉树的根结点值相同,则对两个二叉树的左子树和右子树调用递归。

代码

class Solution {
    public boolean flipEquiv(TreeNode root1, TreeNode root2) {
        if (root1 == null && root2 == null) {
            return true;
        }
        if (root1 == null || root2 == null) {
            return false;
        }
        return root1.val == root2.val && ((flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right))
                || (flipEquiv(root1.left, root2.right) && flipEquiv(root1.right, root2.left)));
    }
}

复杂度分析

  • 时间复杂度: O ( min ⁡ ( m , n ) ) O(\min(m, n)) O(min(m,n)),其中 m m m n n n 分别是两个二叉树的结点数。虽然有两个递归调用分支(分别对应根结点不翻转和翻转),但是由于每个二叉树中的结点值各不相同,因此实际只会执行一个递归调用分支,每个结点被访问一次。

  • 空间复杂度: O ( min ⁡ ( m , n ) ) O(\min(m, n)) O(min(m,n)),其中 m m m n n n 分别是两个二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度等于结点数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值