剑指-- 对称的二叉树
这个和leetoce的101题是一样的,所以笔记也是和101题是一样的。
1,题目:
在这里插入图片描述
2,思路:
方法一:递归:
如果同时满足下面的条件,两个树互为镜像:
1.它们的两个根结点具有相同的值
2.每个树的右子树都与另一个树的左子树镜像对称
我们可以实现这样一个递归函数,通过「同步移动」两个指针的方法来遍历这棵树,p 指针和 q 指针一开始都指向这棵树的根,随后 p 右移时,q 左移,p左移时,q 右移。每次检查当前 p 和 q 节点的值是否相等,如果相等再判断左右子树是否对称。
方法二:队列实现:
现在我们改用队列来实现,思路如下:
1.首先从队列中拿出两个节点(left 和 right)比较
2.将 left 的 left 节点和 right 的 right 节点放入队列
3.将 left 的 right 节点和 right 的 left 节点放入队列
在这里插入图片描述
3,代码:
方法一:递归:
class Solution {
public boolean isSymmetric(TreeNode root) {
/*
如果同时满足下面的条件,两个树互为镜像:
1.它们的两个根结点具有相同的值
2.每个树的右子树都与另一个树的左子树镜像对称
我们可以实现这样一个递归函数,通过「同步移动」两个指针的方法来遍历这棵树,p 指针和 q 指针一开始都指向这棵树的根,随后 p 右移时,q 左移,p左移时,q 右移。每次检查当前 p 和 q 节点的值是否相等,如果相等再判断左右子树是否对称。
*/
return check(root, root);
}
public boolean check(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
return p.val == q.val && check(p.left, q.right) && check(p.right, q.left);
}
}
递归的另一种写法:
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null) {
return true;
}
//调用递归函数,比较左节点,右节点
return dfs(root.left,root.right);
}
boolean dfs(TreeNode left, TreeNode right) {
//递归的终止条件是两个节点都为空
//或者两个节点中有一个为空
//或者两个节点的值不相等
if(left==null && right==null) {
return true;
}
if(left==null || right==null) {
return false;
}
if(left.val!=right.val) {
return false;
}
//再递归的比较 左节点的左孩子 和 右节点的右孩子
//以及比较 左节点的右孩子 和 右节点的左孩子
return dfs(left.left,right.right) && dfs(left.right,right.left);
}
}
方法二:队列实现:
class Solution {
public boolean isSymmetric(TreeNode root) {
/*
现在我们改用队列来实现,思路如下:
1.首先从队列中拿出两个节点(left 和 right)比较
2.将 left 的 left 节点和 right 的 right 节点放入队列
3.将 left 的 right 节点和 right 的 left 节点放入队列
*/
if(root==null || (root.left==null && root.right==null)) {
return true;
}
//用队列保存节点
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
//将根节点的左右孩子放到队列中
queue.add(root.left);
queue.add(root.right);
while(queue.size()>0) {
//从队列中取出两个节点,再比较这两个节点
TreeNode left = queue.removeFirst();
TreeNode right = queue.removeFirst();
//如果两个节点都为空就继续循环,两者有一个为空就返回false
if(left==null && right==null) {
continue;
}
if(left==null || right==null) {
return false;
}
if(left.val!=right.val) {
return false;
}
//将左节点的左孩子, 右节点的右孩子放入队列
queue.add(left.left);
queue.add(right.right);
//将左节点的右孩子,右节点的左孩子放入队列
queue.add(left.right);
queue.add(right.left);
}
return true;
}
}