文章目录
- 题目
- 标题和出处
- 难度
- 题目描述
- 要求
- 示例
- 数据范围
- 进阶
- 解法一
- 思路和算法
- 代码
- 复杂度分析
- 解法二
- 思路和算法
- 代码
- 复杂度分析
题目
标题和出处
标题:对称二叉树
出处:101. 对称二叉树
难度
3 级
题目描述
要求
给你一个二叉树的根结点 root \texttt{root} root,检查它是否轴对称。
示例
示例 1:
输入:
root
=
[1,2,2,3,4,4,3]
\texttt{root = [1,2,2,3,4,4,3]}
root = [1,2,2,3,4,4,3]
输出:
true
\texttt{true}
true
示例 2:
输入:
root
=
[1,2,2,null,3,null,3]
\texttt{root = [1,2,2,null,3,null,3]}
root = [1,2,2,null,3,null,3]
输出:
false
\texttt{false}
false
数据范围
- 树中结点数目在范围 [1, 1000] \texttt{[1, 1000]} [1, 1000] 内
- -100 ≤ Node.val ≤ 100 \texttt{-100} \le \texttt{Node.val} \le \texttt{100} -100≤Node.val≤100
进阶
你可以运用递归和迭代两种方法解决这个问题吗?
解法一
思路和算法
如果二叉树的左子树和右子树对称,则二叉树是对称二叉树。对称二叉树的左子树和右子树的结构和结点值满足左右翻转。
深度优先搜索的做法是,首先判断根结点的左子结点和右子结点是否存在和是否符合对称二叉树的要求,如果左子结点和右子结点存在且符合对称二叉树的要求,则继续对左子树和右子树判断。
由于二叉树的结构具有递归性,因此可以使用递归实现深度优先搜索。
用 p p p 和 q q q 分别表示根结点的左子结点和右子结点。如果 p p p 和 q q q 都为空,则原始二叉树是对称二叉树。如果 p p p 和 q q q 只有一个为空,则原始二叉树的结构不符合对称二叉树的要求,因此原始二叉树不是对称二叉树。这两种情况是递归的终止条件。
对于其余情况,首先判断 p p p 和 q q q 的结点值是否相同,然后执行递归。
-
如果 p p p 和 q q q 的结点值不同,则原始二叉树不是对称二叉树。
-
如果 p p p 和 q q q 的结点值相同,则只有当 p p p 的左子树和 q q q 的右子树对称且 p p p 的右子树和 q q q 的左子树对称时,原始二叉树才是对称二叉树。对 p p p 和 q q q 的左右子树执行递归,判断原始二叉树是否为对称二叉树。
代码
class Solution {
public boolean isSymmetric(TreeNode root) {
return areSymmetric(root.left, root.right);
}
public boolean areSymmetric(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
return p.val == q.val && areSymmetric(p.left, q.right) && areSymmetric(p.right, q.left);
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)。
解法二
思路和算法
也可以使用广度优先搜索遍历二叉树,判断二叉树是否为对称二叉树。
由于需要判断二叉树的左半部分和右半部分是否对称,因此需要同时从两个相反的方向遍历二叉树。使用两个队列分别存储两个方向遍历二叉树访问的结点。初始时将两个二叉树的根结点分别入两个队列,遍历过程中,每次从两个队列分别将一个结点出队列,这两个出队列的结点一定是两个二叉树中对称位置的两个结点,这两个结点分别称为结点一和结点二,执行如下操作。
-
如果两个结点值不同,则两个二叉树的对称位置处的两个结点值不同,因此二叉树不是对称二叉树。
-
如果两个结点值相同,则分别获得两个结点的左子结点和右子结点,如果结点一的左子结点和结点二的右子结点恰好有一个为空,或者结点一的右子结点和结点二的左子结点恰好有一个为空,则二叉树的结构不符合对称二叉树的要求,因此二叉树不是对称二叉树。
-
如果两个结点的左子结点和右子结点的结构符合对称二叉树的要求,则将两个结点的非空子结点分别入相应的队列,如果两个结点的左子结点和右子结点都不为空,则结点一的左子结点和右子结点依次入第一个队列,结点二的右子结点和左子结点依次入第二个队列。
当队列为空时,遍历结束,如果在任意位置,二叉树的结构和结点值都符合对称二叉树的要求,则二叉树是对称二叉树。
代码
class Solution {
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue1 = new ArrayDeque<TreeNode>();
Queue<TreeNode> queue2 = new ArrayDeque<TreeNode>();
queue1.offer(root);
queue2.offer(root);
while (!queue1.isEmpty()) {
TreeNode node1 = queue1.poll();
TreeNode node2 = queue2.poll();
if (node1.val != node2.val) {
return false;
}
TreeNode left1 = node1.left, right1 = node1.right, left2 = node2.left, right2 = node2.right;
if (left1 == null ^ right2 == null) {
return false;
}
if (right1 == null ^ left2 == null) {
return false;
}
if (left1 != null) {
queue1.offer(left1);
queue2.offer(right2);
}
if (right1 != null) {
queue1.offer(right1);
queue2.offer(left2);
}
}
return true;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点在两个方向各访问一次。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是队列空间,每个队列内元素个数不超过 n n n。