题目描述:
给定一棵二叉树,判断其是否是自身的镜像(即:是否对称)
例如: 下面这棵二叉树是对称的
下面这棵二叉树不对称。
![]()
数据范围:节点数满足 0≤n≤1000,节点上的值满足∣val∣≤1000
要求:空间复杂度 O(n),时间复杂度 O(n)
备注:你可以用递归和迭代两种方法解决这个问题
示例1
输入:{1,2,2,3,4,4,3}
返回值:true
示例2
输入:{8,6,9,5,7,7,5}
返回值:false
解法一:递归
思路:
1、如果根节点为空,直接返回true。
2、对根节点的左右子树进行递归判断。
- 如果左右子树都为空,返回true。
- 如果左右子树有一个为空,一个不为空,返回false。
- 如果左右子树的当前值不相等,则返回false。
- 如果左右子树的当前值相等则继续递归,判断左子树的左节点和右子树的右节点,以及左子树的右节点和右子树的左节点是否对称相等。
代码:
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
boolean isSymmetrical(TreeNode pRoot) {
//如果根节点为空,直接返回null
if(pRoot == null){
return true;
}
return isMatch(pRoot.left, pRoot.right);
}
public boolean isMatch(TreeNode pRoot1, TreeNode pRoot2){
//如果左右子树都为空,返回true
if(pRoot1 == null && pRoot2 == null){
return true;
}
//如果左右子树有一个为空,一个不为空,返回false
if((pRoot1 != null && pRoot2 == null) ||( pRoot2 != null && pRoot1 == null)){
return false;
}
//如果值不相等,返回false
if(pRoot1.val != pRoot2.val){
return false;
}
return isMatch(pRoot1.left, pRoot2.right) && isMatch(pRoot1.right, pRoot2.left);
}
}
解法二:非递归
思路:
1、根结点入队列两次(方便后续操作);
2、每次将队列的「前两个」结点出队列,比较其二者是否为空、以及val值;
3、若满足条件,将各自的左右孩子按照相反顺序入队列(如下图,在第二步中,1、2号结点出队列,完成比较后,按照:结点1的左孩子、结点2的右孩子、结点1的右孩子、结点2的左孩子入队列);
4、重复上述步骤直至队列为空。
代码:
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.*;
public class Solution {
boolean isSymmetrical(TreeNode pRoot) {
//如果根节点为空,直接返回null
if(pRoot == null){
return true;
}
//定义队列
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//根节点入队两次
queue.offer(pRoot);
queue.offer(pRoot);
while(!queue.isEmpty()){
//取出队首的两个节点
TreeNode t1 = queue.poll();
TreeNode t2 = queue.poll();
//如果其中一个为空,一个不为空,返回false
if((t1 == null && t2 != null) || (t1 != null && t2 == null)){
return false;
}
//如果都为空,则跳过此次判断
if(t1 == null && t2 == null){
continue;
}
//如果值不相等,,返回false
if(t1.val != t2.val){
return false;
}
//将t1的左子树节点、t2的右子树节点入队
queue.offer(t1.left);queue.offer(t2.right);
//将t2的左子树节点、t1的右子树节点入队
queue.offer(t1.right);queue.offer(t2.left);
}
return true;
}
}