LeetCode 对称二叉树
@author:Jingdai
@date:2020.11.03
题目描述(101题)
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1 / \ 2 2 / \ / \ 3 4 4 3
思路
1.递归方法
如图,可以看出一个对称二叉树的左子树和右子树是镜像对称的,同时左子树的左子树又是和右子树的右子树镜像对称的,左子树的右子树是和右子树的左子树镜像对称的…这不就是一个典型的递归问题吗?根据这个性质即可判断二个树是否是镜像对称的。看下面的代码片段。
/*
* determine whether the two trees are symmetric
*/
public boolean areSymmetric(TreeNode tree1, TreeNode tree2) {
if (tree1 == null && tree2 == null) {
return true;
}
if (tree1 != null && tree2 != null) {
if (tree1.val == tree2.val) {
return areSymmetric(tree1.left, tree2.right)
&& areSymmetric(tree1.right, tree2.left);
} else {
return false;
}
}
return false;
}
然后再判断树是否是镜像对称的,通过判断一个树的左子树和右子树是否为镜像对称的即可完成判断。代码片段如下。
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
return areSymmetric(root.left, root.right);
}
最后的整个代码见后面的代码部分。
2.非递归方法
接下来我们看非递归的方法。如下图,对如下对称二叉树左子树从左到右按层次遍历的结果是 1 2 3 4 5 6 7
,然后对右子树从右到左层次遍历的结果还是 1 2 3 4 5 6 7
。
可以发现如果一个二叉树是镜像对称的,则左子树从左到右层次遍历和右子树从右到左层次遍历的结果是相同的。利用这个性质,每次将左子树按从左到右层次遍历的的顺序向队列中加入一个节点,然后再将右子树按从右到左层次遍历的顺序向队列中加入一个节点,若该二叉树是镜像对称的,则这两个节点值是相同的,如果两个节点值不同,则二叉树必然不是镜像对称的,直接返回;如果层次遍历到最后一个节点值一直是相同的,则说明该二叉树是镜像对称的二叉树。代码见后面代码部分。
代码
1.递归方法
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
return areSymmetric(root.left, root.right);
}
/*
* determine whether the two trees are symmetric
*/
public boolean areSymmetric(TreeNode tree1, TreeNode tree2) {
if (tree1 == null && tree2 == null) {
return true;
}
if (tree1 != null && tree2 != null) {
if (tree1.val == tree2.val) {
return areSymmetric(tree1.left, tree2.right)
&& areSymmetric(tree1.right, tree2.left);
} else {
return false;
}
}
return false;
}
2.非递归方法
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (queue.size() != 0) {
TreeNode tempLeftNode = queue.poll();
TreeNode tempRightNode = queue.poll();
if (tempLeftNode == null && tempRightNode == null) {
continue;
} else if (tempLeftNode == null || tempRightNode == null) {
return false;
} else {
if (tempLeftNode.val == tempRightNode.val) {
queue.offer(tempLeftNode.left);
queue.offer(tempRightNode.right);
queue.offer(tempLeftNode.right);
queue.offer(tempRightNode.left);
} else {
return false;
}
}
}
return true;
}