题目来源:https://leetcode-cn.com/problems/symmetric-tree/
题目描述:
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
方法一:广度周游—递归
思路:
镜像对称条件:
- 两个子树的根节点有相同的值;
- 每一个树的右子树都与另一个树的左子树镜像对称。
判断左子树根节点t1和右子树的根节点t2是否为空:
- 都为空则返回true;
- 只有一个为空,则返回false,其他不再执行。
进行递归:
- 判断t1和t2两个指针当前节点的值是否相等;
- 判断 t1的右子树是否与t2的左子树对称;
- 判断t1的左子树是否与t2的右子树对称。
public public boolean isSymmetric(TreeNode root) {
return isMirror(root, root);
}
public boolean isMirror(TreeNode t1, TreeNode t2) {
//都为空指针,则返回true
if(t1 == null && t2 == null) return true;
//只有一个为空,则返回false
if(t1 == null || t2 == null) return false;
//递归过程:1)判断两个指针当前节点值是否相等;2)判断t1的右子树是否与t2的左子树对称;3)判断t1的左子树是否与t2的右子树对称
return (t1.val == t2.val) && isMirror(t1.right, t2.left) && isMirror(t1.left, t2.right);
}
}
复杂度分析:
假设树上一共 n 个节点。
- 时间复杂度:遍历了整棵树,为O(n)
- 空间复杂度:O(n)
方法二:深度周游—队列(迭代)
思路:
- 引入一个队列(把递归程序改写成迭代程序的常用方法);
- 将根节点入队两次;
- 每次提取两个节点并比较它们的值;
- 将两个节点的左右子节点按相反顺序插入队列中。
class Solution {
public boolean isSymmetric(TreeNode root) {
return isMirror(root, root);
}
public boolean isMirror(TreeNode t1, TreeNode t2) {
// 创建一个队列,保存节点
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 将两个节点放入队列中
queue.add(t1);
queue.add(t2);
while (!queue.isEmpty()) {
// 在队列中取出两个节点并比较它们的值
t1 = queue.poll();
t2 = queue.poll();
// 如果两个节点都为空就继续循环
if(t1 == null && t2 == null) {
continue;
}
// 两者有一个为空或者两者值不想等,返回false
if ((t1 == null || t2 == null) || (t1.val != t2.val)) {
return false;
}
// 将两个节点的左右子节点按相反顺序插入队列中
queue.add(t1.left);
queue.add(t2.right);
queue.add(t1.right);
queue.add(t2.left);
}
return true;
}
}