问题描述
- 给你一个二叉树的根节点 root , 检查它是否轴对称。
示例1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例2:
输入:root = [1,2,2,null,3,null,3]
输出:false
题目来源:LeetCode官方
链接地址:https://leetcode.cn/problems/symmetric-tree/
思路
这题的关键就是理解镜像对称这个概念,root是根结点,只要它的左右子树对称即可,但其左右子树本身是否对称我们不需要管,这里提供了两种思路:递归、队列
核心代码
递归:代码简洁,但理解有点难
public static boolean isSymmetric_dfs(TreeNode root) {
if (root == null){
return true;//空二叉树可看成是对称的,因为都没有
}
return dfs(root.left, root.right);//判断根结点的左右子树
}
//递归实现二叉树对称判断
public static boolean dfs(TreeNode left, TreeNode right) {
if (left == null && right == null){//左结点和右结点都空即对它们的父节点来说是对称的
return true;
}
else if(left == null || right == null){//有一个空,另一个不空,证明结构不对称
return false;
}else if (left.val != right.val){//如果结构对称,但数值不相等也是不对称的
return false;
}else{
//判断左子树的左结点与右子树的右结点,左子树的右结点与右子树的左结点是否相等,全部相等才是true
return dfs(left.left, right.right) && dfs(left.right, right.left);
}
}
队列:
//尝试用队列实现
public static boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
//先将根结点的左右结点入队列
queue.offer(root.left);
queue.offer(root.right);
//队列不空
while(!queue.isEmpty()){
//出队列比较
TreeNode left = queue.poll();
TreeNode right = queue.poll();
if (left == null && right == null){//如果两个都null,则进入下一次的比较
continue;
}else if (left == null || right == null || left.val != right.val){
//只要结构不对称,或者对称位置上的值不相等,就直接false
return false;
}
//比较完left和right结点,接着比较它们的左右结点
//这里的入队列的顺序要按套来:left的左结点对应right的右结点,left的右结点对应right的左结点
queue.offer(left.left);
queue.offer(right.right);
queue.offer(left.right);
queue.offer(right.left);
}
return true;//如果比较完后队列空了,都没有进入else if那一条语句,那就证明是对称的
}
运行效果
递归:
队列:
完整源代码
package com.easy;
import java.util.LinkedList;
import java.util.Queue;
public class isSymmetric {
public static void main(String[] args) {
/**
* 构建对称二叉树
* 1
* 2 2
* 3 4 4 3
*/
TreeNode n3 = new TreeNode(3);
TreeNode n4 = new TreeNode(4);
TreeNode n5 = new TreeNode(4);
TreeNode n6 = new TreeNode(3);
TreeNode n1 = new TreeNode(2, n3, n4);
TreeNode n2 = new TreeNode(2, n5, n6);
TreeNode root = new TreeNode(2, n1, n2);
System.out.println(isSymmetric(root));
System.out.println(isSymmetric_dfs(root));
}
//尝试用队列实现
public static boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
//先将根结点的左右结点入队列
queue.offer(root.left);
queue.offer(root.right);
//队列不空
while(!queue.isEmpty()){
//出队列比较
TreeNode left = queue.poll();
TreeNode right = queue.poll();
if (left == null && right == null){//如果两个都null,则进入下一次的比较
continue;
}else if (left == null || right == null || left.val != right.val){
//只要结构不对称,或者对称位置上的值不相等,就直接false
return false;
}
//比较完left和right结点,接着比较它们的左右结点
//这里的入队列的顺序要按套来:left的左结点对应right的右结点,left的右结点对应right的左结点
queue.offer(left.left);
queue.offer(right.right);
queue.offer(left.right);
queue.offer(right.left);
}
return true;//如果比较完后队列空了,都没有进入else if那一条语句,那就证明是对称的
}
public static boolean isSymmetric_dfs(TreeNode root) {
if (root == null){
return true;//空二叉树可看成是对称的,因为都没有
}
return dfs(root.left, root.right);//判断根结点的左右子树
}
//递归实现二叉树对称判断
public static boolean dfs(TreeNode left, TreeNode right) {
if (left == null && right == null){//左结点和右结点都空即对它们的父节点来说是对称的
return true;
}
else if(left == null || right == null){//有一个空,另一个不空,证明结构不对称
return false;
}else if (left.val != right.val){//如果结构对称,但数值不相等也是不对称的
return false;
}else{
//判断左子树的左结点与右子树的右结点,左子树的右结点与右子树的左结点是否相等,全部相等才是true
return dfs(left.left, right.right) && dfs(left.right, right.left);
}
}
}