class TreeNode {
int val;
TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
public class SymmetricBinaryTree {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true; // 空树是对称的
}
return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode left, TreeNode right) {
if (left == null && right == null) {
return true; // 左右子树都为空,是对称的
}
if (left == null || right == null) {
return false; // 一个为空,一个不为空,不对称
}
// 判断当前节点值相等,并且左子树的左子树与右子树的右子树镜像对称,
// 且左子树的右子树与右子树的左子树镜像对称
return (left.val == right.val) &&
isMirror(left.left, right.right) &&
isMirror(left.right, right.left);
}
public static void main(String[] args) {
// 创建一个对称二叉树的例子
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(2);
root.left.left = new TreeNode(3);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(3);
SymmetricBinaryTree checker = new SymmetricBinaryTree();
boolean isSymmetric = checker.isSymmetric(root);
System.out.println("Is the tree symmetric? " + isSymmetric);
}
}
使用迭代的方式通常需要借助队列(Queue)来模拟递归的过程。具体思路是利用队列按层遍历二叉树,并逐层判断是否对称:
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
int val;
TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
public class SymmetricBinaryTree {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true; // 空树是对称的
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode leftNode = queue.poll();
TreeNode rightNode = queue.poll();
if (leftNode == null && rightNode == null) {
continue; // 左右子树都为空,继续下一层比较
}
if (leftNode == null || rightNode == null) {
return false; // 一个为空,一个不为空,不对称
}
if (leftNode.val != rightNode.val) {
return false; // 节点值不相等,不对称
}
// 将左子树的左节点、右子树的右节点和左子树的右节点、右子树的左节点加入队列,以便下一层比较
queue.offer(leftNode.left);
queue.offer(rightNode.right);
queue.offer(leftNode.right);
queue.offer(rightNode.left);
}
return true;
}
public static void main(String[] args) {
// 创建一个对称二叉树的例子
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(2);
root.left.left = new TreeNode(3);
root.left.right = new TreeNode(4);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(3);
SymmetricBinaryTree checker = new SymmetricBinaryTree();
boolean isSymmetric = checker.isSymmetric(root);
System.out.println("Is the tree symmetric? " + isSymmetric);
}
}
在这个实现中,我们使用一个队列来模拟递归的过程,不断将每一层的左子树和右子树的对应节点入队,并比较它们的值。如果出现不对称的情况,直接返回 false。最终,如果队列为空,则说明整个二叉树是对称的,返回 true。
方式 | 优势 | 劣势 |
---|---|---|
递归 | 简洁、直观 、可读性好 | 栈空间占用,可能导致栈溢出 |
迭代 | 性能较好 | 代码可能相对冗长,需要显式数据结构维护 |
是否可以对递归实现进行优化,减少不必要的调用或重复计算呢?
早期终止条件: 在递归函数的开始,可以加入一些早期终止条件,以尽早地判断当前子树是否不对称,从而避免进一步的递归调用。例如,如果左右节点值不相等,可立即返回 false。
private boolean isMirror(TreeNode left, TreeNode right) {
if (left == null && right == null) {
return true;
}
if (left == null || right == null || left.val != right.val) {
return false;
}
// 继续递归判断
return isMirror(left.left, right.right) && isMirror(left.right, right.left);
}
还有没有其他或者更好的优化思路呢,评论区一起开麦讨论吧