给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [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
说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分。
思路有两种:一种是DFS的思想,一种是BFS的思想
public boolean isSymmetric(TreeNode root) {
//这里我判断根节点为空和左右孩子为空作为特殊情况
if (root == null || root.left == null && root.right == null) {
return true;
}
//双向队列
LinkedList<TreeNode> queue = new LinkedList<>();
//添加根节点
queue.addLast(root);
//每次while循环开始时,保存队列的总数,方便后面的for循环
int count;
//判断是不是根节点,我把根节点作为特殊情况处理,因为后面的for循环中倘若count为1,
//则不会执行for循环里面的语句,当然各位也可以自己改进改进
boolean head = true;
//判断队列是否为空
while (!queue.isEmpty()) {
//保存循环开始时,队列的里面数据的总数
count = queue.size();
//记录当前一行每个节点的数据
TreeNode[] nodes = new TreeNode[count];
//记录当前一行所有数据的值,若为空则存为Integer的最小值
int[] val = new int[count];
for (int i = 0; i < count; i++) {
//其中pollFirst获取头部元素并删除,如果头部元素为null则不会抛异常
nodes[i] = queue.pollFirst();
if (nodes[i] == null) {
val[i] = Integer.MIN_VALUE;
continue;
}
val[i] = nodes[i].val;
}
//类似于回文的样子,进行一一的比较
for (int i = 0; i < count / 2; i++) {
if (val[i] != val[count - 1 - i]) {
return false;
}
}
//判断为根节点,若为则添加根节点的左右子树
if (head) {
queue.addFirst(nodes[0].left);
queue.addLast(nodes[0].right);
head = false;
continue;
}
//for循环,判断当前行的每个树的左右子树与其对称的另一个左右子树是否不为空,都为空则不添加进队列,
//一边树为空,另一边不为空则直接返回false表示已经不对称了
for (int i = 0; i < count / 2; i++) {
if (nodes[i].left == null && nodes[count - 1 - i].right != null) {
return false;
} else if (nodes[i].left != null && nodes[count - 1 - i].right == null) {
return false;
} else if (nodes[i].right == null && nodes[count - 1 - i].left != null) {
return false;
} else if (nodes[i].right != null && nodes[count - 1 - i].left == null) {
return false;
}
if (nodes[i].left != null && nodes[count - 1 - i].right != null) {
queue.addFirst(nodes[i].left);
queue.addLast(nodes[count - 1 - i].right);
}
if (nodes[i].right != null && nodes[count - 1 - i].left != null) {
queue.addFirst(nodes[i].right);
queue.addLast(nodes[count - 1 - i].left);
}
}
}
return true;
}