leetcode
leetcode 101 ~ 150
对称二叉树

对称二叉树

难度:

标签:

题目描述

给你一个二叉树的根节点 root , 检查它是否轴对称。

 

示例 1:

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

示例 2:

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

 

提示:

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

 

进阶:你可以运用递归和迭代两种方法解决这个问题吗?

代码结果

运行时间: 44 ms, 内存: 15.1 MB


/*
 * 思路:
 * 与常规递归方法类似,但使用Java Stream来实现。
 * 利用Java Stream来简化数据操作和代码的可读性。
 */
 
import java.util.stream.Stream;
 
public class Solution {
    public boolean isSymmetric(TreeNode root) {
        // 空树是对称的
        if (root == null) return true;
        // 从根节点的左右子树开始判断
        return isMirror(root.left, root.right);
    }
 
    private boolean isMirror(TreeNode t1, TreeNode t2) {
        // 利用Stream来判断两节点是否相等并进行递归
        return Stream.of(t1, t2)
            .allMatch(n -> n == null) ||
            (t1 != null && t2 != null && t1.val == t2.val &&
            isMirror(t1.left, t2.right) &&
            isMirror(t1.right, t2.left));
    }
}
 

解释

方法:

这个题解使用递归的方式来判断二叉树是否对称。主要思路是同时从左右子树开始递归遍历,比较对应位置节点的值是否相等。如果左右子树都为空,说明对称;如果只有一个子树为空,说明不对称;如果两个子树的节点值不相等,也说明不对称。在递归过程中,要将左子树的左孩子和右子树的右孩子进行比较,左子树的右孩子和右子树的左孩子进行比较。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在递归函数中,当左右子树都为空时直接返回True,这种处理方式是否能正确处理所有对称树的情况,包括只有一个根节点的树?
是的,这种处理方式能正确处理所有对称树的情况。当二叉树的左右子树都为空时,意味着到达了叶子节点的下一层,这是对称的基本情况。对于只有一个根节点的树,根节点的左右子树都为空,因此在根节点的递归检查中也会返回True,从而判断整棵树是对称的。
🦆
递归解法中,如果左右子树的结构相同但是节点值不同,如何确保递归仍然能准确判断出不对称?
在递归解法中,检查对称性不仅涉及结构的比较,还涉及节点值的比较。递归函数首先检查当前比较的两个节点的值是否相等。如果不相等,函数会直接返回False,表明树不对称。只有当节点值相等时,才会继续递归比较其他对应的子节点。这确保了即使左右子树的结构相同,节点值不同也会被正确地识别为不对称。
🦆
您提到可以使用迭代和递归两种方法解决问题,请问迭代方法具体是如何实现的?
迭代方法通常使用队列来模拟递归过程。首先,将根节点的左右子节点入队。然后,每次从队列中取出两个节点进行比较,并将它们的子节点按对称顺序入队:先左节点的左子节点与右节点的右子节点,然后左节点的右子节点与右节点的左子节点。如果在任何时候节点值不相等,或者一个节点为空而另一个不为空,则判断树不对称。如果队列为空,表明已经完成了所有对应节点的比较,且所有比较都表明节点对称,因此树是对称的。
🦆
在递归函数中,存在多处对节点为空的检查,是否可以通过优化减少这些检查以提高代码效率?
可以通过调整逻辑稍微减少一些为空的检查。例如,可以将两个节点都为空的情况和其中一个节点为空的情况合并处理。具体做法是,在递归函数中,如果其中一个节点为空,就检查另一个节点是否也为空。如果两个节点都为空,返回True;如果只有一个为空,则返回False。这样可以将检查节点是否为空的次数减少到每个节点只检查一次。

相关问题