携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
一、题目
LeetCode 对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
提示:
树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
二、题解
给定一颗二叉树需要判断二叉树是否是对称的,如果二叉树与其镜像二叉树是一致相同就是对称的。
方法一
可以通过遍历二叉树查询节点值是否是对称的,同时使用两个指针遍历二叉树节点,而指针就分部指向对称的节点,然后判断节点值是否相同即可。具体的使用dfs深度优先搜索来遍历二叉树节点,比较两个子树节点,如果两个指针的节点为空的话就结束遍历返回true表示两个节点其实都一样,如果有一个节点为空一个节点不为空的话就返回false说明这两个对称的节点不一致,然后再比较两个指针节点的值,如果节点值不相等的话就需要返回false表示节点不同整给树也就不同了。最后再递归的比较子树节点,首先需要比较的是对称的两对节点,所以需要比较左子树的左节点和右子树的右节点,以及比较左子树的右节点和右子树的左节点。
方法二
同样可以使用bfs广度优先搜索遍历二叉树,使用队列存储节点遍历,同时存储左右对称的节点到队列中,初始的存储两个root节点,然后取出两个节点判断如果节点都为空就忽略,否则如果其中一个节点为空的话返回false说明节点不一致,然后判断节点值是否一致,如果不一致也返回false,最后将左子树的左节点和右子树的右节点加入队列,还有左子树的右节点和右子树的左节点也加入队列中继续遍历判断。
三、代码
方法一 Java代码
class Solution {
public boolean isSymmetric(TreeNode root) {
return dfs(root, root);
}
public boolean dfs(TreeNode p1, TreeNode p2) {
if (p1 == null && p2 == null) {
return true;
}
if (p1 == null || p2 == null) {
return false;
}
if (p1.val != p2.val) {
return false;
}
return dfs(p1.left, p2.right) && dfs(p1.right, p2.left);
}
}
时间复杂度:O(n),需要遍历一次二叉树节点。
空间复杂度:O(n),递归消耗栈空间。
方法二 Java代码
class Solution {
public boolean isSymmetric(TreeNode root) {
TreeNode p1 = root;
TreeNode p2 = root;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(p1);
queue.offer(p2);
while (!queue.isEmpty()) {
p1 = queue.poll();
p2 = queue.poll();
if (p1 == null && p2 == null) {
continue;
}
if (p1 == null || p2 == null) {
return false;
}
if (p1.val != p2.val) {
return false;
}
queue.offer(p1.left);
queue.offer(p2.right);
queue.offer(p1.right);
queue.offer(p2.left);
}
return true;
}
}
时间复杂度:O(n),需要遍历一次二叉树节点。
空间复杂度:O(n),使用队列存储节点辅助遍历二叉树。