一、题目描述
给你一个二叉树的根节点 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
二、解题思路
- 要检查一个二叉树是否轴对称,我们可以定义一个辅助函数,该函数接受两个节点作为参数,并检查这两个节点是否是彼此的镜像。
- 在这个辅助函数中,我们首先检查两个节点是否都为空,如果是,则它们是镜像。
- 如果两个节点中有一个为空,另一个不为空,则它们不是镜像。
- 如果两个节点的值不相等,则它们不是镜像。
- 递归地,我们检查第一个节点的左子节点和第二个节点的右子节点是否是镜像,以及第一个节点的右子节点和第二个节点的左子节点是否是镜像。
- 如果上述所有条件都满足,则两个节点是镜像。
三、具体代码
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
return (p.val == q.val) && isMirror(p.left, q.right) && isMirror(p.right, q.left);
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 我们需要遍历树中的每个节点一次,以确定它们是否轴对称。
- 假设树中有
n
个节点,那么时间复杂度是O(n)
,因为每个节点只被访问一次。
2. 空间复杂度
- 递归调用会使用栈空间,其空间复杂度取决于树的高度。
- 在最坏的情况下,树完全不平衡,例如每个节点都只有左子节点或者只有右子节点,递归的深度会是
O(n)
,因此空间复杂度也是O(n)
。 - 在最好的情况下,树是完全平衡的,递归的深度是
O(log n)
,因此空间复杂度是O(log n)
。
综上所述,时间复杂度是 O(n)
,空间复杂度在最坏情况下是 O(n)
,在最好情况下是 O(log n)
。
五、总结知识点
-
递归:这是一种常用的算法技巧,用于解决可以分解为更小子问题的问题。在这个问题中,我们检查一个二叉树是否轴对称,可以通过递归地检查它的子树是否互为镜像来实现。
-
二叉树遍历:代码中隐式地使用了深度优先搜索(DFS)来遍历二叉树的节点。这是一种常用的二叉树遍历算法,它通过递归先访问根节点,然后遍历左子树,最后遍历右子树。
-
引用比较:在Java中,
==
操作符用于比较引用类型时,会比较两个引用是否指向堆内存中的同一个对象。在这个问题中,我们使用==
来检查两个节点是否都为null
。 -
逻辑运算符:代码中使用了逻辑与运算符
&&
来组合两个布尔表达式的结果。这要求两个表达式都为true
时,整个表达式的结果才为true
。 -
条件语句:代码中使用了
if-else
语句来根据节点的状态做出决策。这是编程中基本的控制流结构,用于根据条件执行不同的代码路径。 -
函数定义:代码定义了一个名为
isSymmetric
的函数,它接受一个TreeNode
类型的参数,并返回一个布尔值。这是面向对象编程中封装和抽象的基本概念。 -
递归终止条件:在递归函数中,必须有一个或多个终止条件以避免无限递归。在这个问题中,递归的终止条件是当两个节点都为
null
时返回true
,或者当一个节点为null
而另一个不是时返回false
。 -
节点结构:代码中使用了
TreeNode
类来表示二叉树的节点,每个节点包含一个整数值val
和两个指向其子节点的引用left
和right
。这是二叉树在计算机科学中的基本表示方式。 -
对称性检查:代码中实现了
isMirror
函数,用于检查两个节点是否是彼此的镜像。这是解决轴对称问题的关键,通过比较对应节点的值和结构来判断。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。