算法21: 对称二叉树

这篇博客介绍了如何检查一个二叉树是否是对称的,提供了递归和迭代两种解法。在迭代方案中,使用了Queue队列进行节点的比较,虽然效率稍慢,但确保了正确性。递归方案则更直观,通过比较左右子树的镜像关系来确定对称性。博主反思了自己的思维局限,并表示在实际应用中可能会倾向于使用递归解法。
摘要由CSDN通过智能技术生成

一、需求

给你一个二叉树的根节点 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

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

二、思路图

迭代思路图

请添加图片描述

三、代码

提供的TreeNode类

package com.bessky.pss.wzw.SuanFa;

/**
 * 94. 二叉树的中序遍历
 *
 * @author 王子威
 * @date 2022/7/27
 */
public class TreeNode
{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) {this.val = val;}
    TreeNode(int val, TreeNode left, TreeNode right){
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

测试方法

/**
 * 入口
 *      101. 对称二叉树
 *      1.创建链表root
 * 输入:
 *      TreeNode root = [1,2,2,3,4,4,3]
 * 输出:
 *      result = true
 * 解释:
 *      1.递归
 *      2.迭代(Queue队列)
 */
@Test
public void suanfa21()
{
    // 创建树
    TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(3), new TreeNode(4)), new TreeNode(2, new TreeNode(4), new TreeNode(3)));

    // 调用方法:递归
    boolean result1 = this.isSymmetric(root);
    System.out.println("results1 = " + result1);

    // 调用方法:迭代
    boolean result2 = this.isSymmetricIteration(root);
    System.out.println("results2 = " + result2);
}

迭代方案

/**
 * 迭代方案
 *      效率较慢,没有递归快
 *
 * @param root 二叉树
 * @return
 */
public boolean isSymmetricIteration(TreeNode root)
{
    // Queue队列 和 堆的处理方案一样,都是先进先出(FIFO)的数据结构
    Queue<TreeNode> treeNodes = new LinkedList<>();

    // 存入根节点的 左子树 和 右子树
    treeNodes.offer(root.left);
    treeNodes.offer(root.right);

    // 如果Queue队列不为空就循环比较
    while (!treeNodes.isEmpty())
    {
        // 获取存入的左子树 和 右子树 (因为先进先出,所以可以确认顺序)
        TreeNode rootLeft = treeNodes.poll();
        TreeNode rootRight = treeNodes.poll();

        // 两个都等于null, 所以没有子节点了,就继续判断队列中是否还有值,有则比较,无则结束,返回true
        if (rootLeft == null && rootRight == null)
        {
            continue;
        }

        // 左子树 或 右子树,如果有一个是null,就说明不相等,直接返回false,因为上面的判断,所以不可能两个都是null
        if (rootLeft == null || rootRight == null)
        {
            return false;
        }

        // 左子树 比较 右子树 的值不相等,直接返回false
        if (rootLeft.val != rootRight.val)
        {
            return false;
        }

        // 存入 左子树的左子树 和 右子树的右子树,这样当取出比较相等就说明是镜像
        treeNodes.offer(rootLeft.left);
        treeNodes.offer(rootRight.right);

        // 存入 左子树的右子树 和 右子树的左子树,这样当取出比较相等就说明是镜像
        treeNodes.offer(rootLeft.right);
        treeNodes.offer(rootRight.left);
    }
    // 当执行到这里说明树两边是镜像的
    return true;
}

递归方案

/**
 * 递归方案
 *
 * @param root 二叉树
 * @return
 */
public boolean isSymmetric(TreeNode root)
{
    return isSymmetricRecursion(root.left, root.right);
}
/**
 * 递归方法体
 *
 * @param rootLeft 左节点
 * @param rootRight 右节点
 * @return
 */
public boolean isSymmetricRecursion(TreeNode rootLeft, TreeNode rootRight)
{
    if (rootLeft == null && rootRight == null)
    {
        return true;
    }
    else if (rootLeft == null || rootRight == null)
    {
        return false;
    }
    else
    {
        return rootLeft.val == rootRight.val && isSymmetricRecursion(rootLeft.left, rootRight.right) && isSymmetricRecursion(rootLeft.right, rootRight.left);
    }
}

结果图

作者:王子威

四、总结

  • 学习了对称二叉树算法
  • 还是还是感觉到了菜鸡,自己思考尽然没想到这方面,有想到迭代,但未写出
  • 学习了Queue队列
  • 在日常中如果遇到,还是用递归会感觉方便些
  • 迭代的效率反而满慢了些
  • 算法兴趣+1 总:21
  • 加强了对算法的分析能力
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值