题目: 给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树[1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个[1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/symmetric-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
该题还是考察对树结构的遍历,判断一棵树是否是对称的树,从大的方面来看(从根节点来看), 需要判断左子树是否与右子树是否为对称的树即可。从子树上看,例如例1中的第二层的2号节点和3号节点(根节点为第一层,往下增长,从每层的左边开始标号) 只需要判断2号节点的左子树与3号节点的右子树是否相同,2号节点的右子树与3号节点的左子树是否相同。 从子树开始就可以利用递归对子树的对称性进行判断。 直接使用递归的方法需要考虑栈的深度,如果树的深度大于了栈的深度,需要考虑使用辅助结构来迭代遍历。
使用递归的解法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) {
return true;
} else {
return isSymmetric(root.left,root.right);
}
}
private boolean isSymmetric(TreeNode left,TreeNode right) {
if(left == null && right == null) {
return true;
} else if (left == null || right == null) {
return false;
}
if(left.val == right.val) {
// 检查左子树的左子树与右子树的右子树是否一致
return isSymmetric(left.left,right.right)
// 检查左子树的右子树与右子树的左子树是否一致
&& isSymmetric(left.right,right.left);
}
return false;
}
}
使用迭代的方式的解法
解法其实与递归的逻辑是一致的,只是相对于递归自己实现了栈的处理。此处用了两个栈,主要是为了进行隔离左子树和右子树的节点,避免混淆,用一个栈或者用一个队列都是可以实现的
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) {
return true;
}
//新建两个栈结构存储左子树的节点和右子树节点
Stack<TreeNode> leftStack = new Stack();
Stack<TreeNode> rightStack = new Stack();
// 先将左右子树的节点根节点入栈
leftStack.push(root.left);
rightStack.push(root.right);
while(!leftStack.empty() && !rightStack.empty()) {
// 取出节点,并进行值判断
TreeNode left = leftStack.pop();
TreeNode right = rightStack.pop();
if(left == null && right == null) {
continue;
} else if(left == null || right == null) {
return false;
}
if(left.val == right.val) {
// 将子节点压栈
// 左子树先压右孩子,然后左孩子
leftStack.push(left.right);
leftStack.push(left.left);
// 右子树先压左孩子,然后右孩子
rightStack.push(right.left);
rightStack.push(right.right);
}else {
return false;
}
}
return true;
}
}