leetcode 101 : 对称二叉树

# leetcode 101 : 对称二叉树

给你一个二叉树的根节点 `root` , 检查它是否轴对称。

**示例 1:**

![img](https://assets.leetcode.com/uploads/2021/02/19/symtree1.jpg)

```
输入:root = [1,2,2,3,4,4,3]
输出:true
```

**示例 2:**

![img](https://assets.leetcode.com/uploads/2021/02/19/symtree2.jpg)

```
输入:root = [1,2,2,null,3,null,3]
输出:false
```

**提示:**

- 树中节点数目在范围 `[1, 1000]` 内
- `-100 <= Node.val <= 100`

**进阶:**你可以运用递归和迭代两种方法解决这个问题吗?

Related Topics

深度优先搜索

广度优先搜索

二叉树

## 思路1:递归(实际上也是深度优先遍历)

分析:判断一个树是否对称,可以转换成判断一个树的左右子树是否对称。

对称条件:两个子树A和B

* A和B的根节点相等。
* A的左子树与B的右子树对称。
* A的右子树与B的左子树对称。

```java
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric(root.left,root.right);
    }
    public boolean isSymmetric(TreeNode root1,TreeNode root2){
        //当根都为空 说明是叶子节点 直接返回tree
        if(root1==null&&root2==null){
            return true;
        }
        //当一个为空时,不对称
        if((root1!=null && root2==null) || (root1==null&&root2!=null)){
            return false;
        }
        
        if(root1.val != root2.val){ //当前值不等于 直接返回false
            return false;
        }
        //判断root1的左子树是否和root2的右子树对称

        if(isSymmetric(root1.left,root2.right)==false){
            return false;
        }
         //判断root1的右子树是否和root2的左子树对称
        if(isSymmetric(root1.right,root2.left) == false){
            return false;
        }
        return true;
    }
}
解答成功:
            执行耗时:0 ms,击败了100.00% 的Java用户
            内存消耗:39.7 MB,击败了12.00% 的Java用户
```

对上述思路优化:

```java
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric(root.left,root.right);
    }
    public boolean isSymmetric(TreeNode root1,TreeNode root2){
        //当根都为空 说明是叶子节点 直接返回tree
        if(root1==null&&root2==null){
            return true;
        }
        //当一个为空时,不对称
        if(root1==null || root2==null){
            return false;
        }
        //只有根节点相等 root1的左子树与root2的右子树对称 root1的右子树与root2的左子树对称
        //才对称
        return root1.val == root2.val && isSymmetric(root1.left,root2.right) && isSymmetric(root1.right,root2.left);

    }
}
```

## 思路2:队列 (广度优先遍历)

借鉴思路1, 广度优先遍历需要使用队列,可以把左右子树A和B放入队列中。

* 从队列中取出A和B,比较A和B的值是否相等
  * 不相等就不对称。
* 相等时,把A的左孩子放入队列中,接着放入B的右孩子,再放A的右孩子和B的左孩子。
* 直到最终,如果队列为空,说明是对称树。

```java
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric(root.left,root.right);
    }
    public boolean isSymmetric(TreeNode root1,TreeNode root2){
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root1);
        queue.offer(root2);
        while(!queue.isEmpty()){
            TreeNode p = queue.poll();
            TreeNode q = queue.poll();
            //如果都为空 说明父节点是叶子节点 直接跳过
            if(p == null && q == null){
                continue;
            }
            //如果其中一个为空 另一个不为空
            //或者 p和q的元素不相等 说明不对称的
            if(p==null || q == null || p.val != q.val){
                return false;
            }
            //如果当前节点对称 判断子树
            queue.offer(p.left);//p的左子树和q的右子树对称
            queue.offer(q.right);

            queue.offer(p.right);//p的右子树与q的左子树对称
            queue.offer(q.left);
        }
        return true;
    }
}
    解答成功:
            执行耗时:1 ms,击败了24.13% 的Java用户
            内存消耗:39.5 MB,击败了18.54% 的Java用户
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值