坚持刷题 |对称二叉树

news2024/12/22 19:45:29

文章目录

  • 题目
  • 考察点
  • 代码实现
  • 实现总结
  • 扩展
    • 用迭代的方式判断是否为对称二叉树
    • 递归和迭代的对比
    • 可能的扩展提问

坚持刷题,老年痴呆追不上我,今天真的好累,就不难为自己了,刷个简单级别的吧:对称二叉树

题目

101.对称二叉树在这里插入图片描述

考察点

  • 递归能力: 能否使用递归来解决问题。
  • 树的基本操作:能否正确地访问节点的值,左子树,右子树等。
  • 边界条件处理: 能否正确处理空树的情况。
  • 镜像对称性的理解: 能否理解对称二叉树的定义。
  • 时间和空间复杂度: 解决问题的方法是否具有合理的时间和空间复杂度。

代码实现

class TreeNode {
    int val;
    TreeNode left, right;
    
    public TreeNode(int val) {
        this.val = val;
        this.left = this.right = null;
    }
}

public class SymmetricBinaryTree {
    
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true; // 空树是对称的
        }
        return isMirror(root.left, root.right);
    }

    private boolean isMirror(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true; // 左右子树都为空,是对称的
        }
        if (left == null || right == null) {
            return false; // 一个为空,一个不为空,不对称
        }
        // 判断当前节点值相等,并且左子树的左子树与右子树的右子树镜像对称,
        // 且左子树的右子树与右子树的左子树镜像对称
        return (left.val == right.val) &&
               isMirror(left.left, right.right) &&
               isMirror(left.right, right.left);
    }

    public static void main(String[] args) {
        // 创建一个对称二叉树的例子
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(2);
        root.left.left = new TreeNode(3);
        root.left.right = new TreeNode(4);
        root.right.left = new TreeNode(4);
        root.right.right = new TreeNode(3);

        SymmetricBinaryTree checker = new SymmetricBinaryTree();
        boolean isSymmetric = checker.isSymmetric(root);
        System.out.println("Is the tree symmetric? " + isSymmetric);
    }
}

实现总结

  • 边界条件处理: 空树是对称的。
  • 镜像对称性的理解: 要正确理解对称二叉树的定义,即左子树和右子树镜像对称。
  • 时间复杂度:O(n)。递归的实现是通过深度优先遍历,每个节点只访问一次。在最坏情况下,需要访问二叉树的所有节点,因此时间复杂度是线性的,与节点数成正比。
  • 空间复杂度:O(n)。空间复杂度主要取决于递归调用的深度,因为每一层递归调用都会占用一定的栈空间。在这个对称二叉树的递归实现中,递归调用的深度最多为树的高度。对于平衡二叉树来说,树的高度近似 log(n),其中 n 是节点数。但在最坏情况下,如果二叉树是一条链,树的高度就是节点数 n。

扩展

用迭代的方式判断是否为对称二叉树

使用迭代的方式通常需要借助队列(Queue)来模拟递归的过程。具体思路是利用队列按层遍历二叉树,并逐层判断是否对称:

import java.util.LinkedList;
import java.util.Queue;

class TreeNode {
    int val;
    TreeNode left, right;

    public TreeNode(int val) {
        this.val = val;
        this.left = this.right = null;
    }
}
public class SymmetricBinaryTree {

    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true; // 空树是对称的
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);

        while (!queue.isEmpty()) {
            TreeNode leftNode = queue.poll();
            TreeNode rightNode = queue.poll();

            if (leftNode == null && rightNode == null) {
                continue; // 左右子树都为空,继续下一层比较
            }

            if (leftNode == null || rightNode == null) {
                return false; // 一个为空,一个不为空,不对称
            }

            if (leftNode.val != rightNode.val) {
                return false; // 节点值不相等,不对称
            }

            // 将左子树的左节点、右子树的右节点和左子树的右节点、右子树的左节点加入队列,以便下一层比较
            queue.offer(leftNode.left);
            queue.offer(rightNode.right);
            queue.offer(leftNode.right);
            queue.offer(rightNode.left);
        }

        return true;
    }

    public static void main(String[] args) {
        // 创建一个对称二叉树的例子
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(2);
        root.left.left = new TreeNode(3);
        root.left.right = new TreeNode(4);
        root.right.left = new TreeNode(4);
        root.right.right = new TreeNode(3);

        SymmetricBinaryTree checker = new SymmetricBinaryTree();
        boolean isSymmetric = checker.isSymmetric(root);
        System.out.println("Is the tree symmetric? " + isSymmetric);
    }
}

在这个实现中,我们使用一个队列来模拟递归的过程,不断将每一层的左子树和右子树的对应节点入队,并比较它们的值。如果出现不对称的情况,直接返回 false。最终,如果队列为空,则说明整个二叉树是对称的,返回 true。

递归和迭代的对比

方式优势劣势
递归简洁、直观 、可读性好栈空间占用,可能导致栈溢出
迭代性能较好代码可能相对冗长,需要显式数据结构维护
  • 如果树规模较小且对代码简洁性有要求,可以选择递归。 递归在解决对称二叉树问题时通常能够提供简洁而清晰的解决方案。
  • 如果树规模较大或者对性能有要求,可以选择迭代。 迭代通常在大规模数据的情况下性能更好,尤其是当树的深度较大时。

可能的扩展提问

是否可以对递归实现进行优化,减少不必要的调用或重复计算呢?

早期终止条件: 在递归函数的开始,可以加入一些早期终止条件,以尽早地判断当前子树是否不对称,从而避免进一步的递归调用。例如,如果左右节点值不相等,可立即返回 false。

private boolean isMirror(TreeNode left, TreeNode right) {
    if (left == null && right == null) {
        return true;
    }
    if (left == null || right == null || left.val != right.val) {
        return false;
    }

    // 继续递归判断
    return isMirror(left.left, right.right) && isMirror(left.right, right.left);
}

还有没有其他或者更好的优化思路呢🤔,评论区一起开麦讨论🎤吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据开发之SparkSQL

第 1 章&#xff1a;spark sql概述 1.1 什么是spark sql 1、spark sql是spark用于结构化数据处理的spark模块 1&#xff09;半结构化数据&#xff08;日志数据&#xff09; 2&#xff09;结构化数据&#xff08;数据库数据&#xff09; 1.2 为什么要有sparksql hive on s…

如何开发一款独立游戏?

如何开发一款独立游戏&#xff1f; 2023年&#xff0c;Steam平台共发行了14533款游戏&#xff0c;我们可以清晰地看到独立游戏市场的蓬勃发展和不断增长的活力。我们从SteamDB数据统计网站获悉&#xff0c;2023年Steam平台的游戏发行数量比2022年的12562款增加了1971款&#xf…

理想汽车大模型算法工程师面试,被问的瑟瑟发抖。。。。

最近我们技术群的一位小伙伴&#xff0c;分享了他面试理想汽车大模型算法工程师的经历与经验。 今天整理后分享给大家&#xff0c;如果你对这块感兴趣&#xff0c;可以文末加入我们的技术&面试讨论群 一面&#xff08;1.5h&#xff0c;感觉有点难&#xff09; 自我介绍&…

推荐收藏!48道数据分析师高频面试题汇总!

大家好&#xff0c;最近很多小伙伴私信我&#xff0c;讲一下数据分析的面试题&#xff0c;今天给大家整理了48道数据分析师面试时被频繁问到的题目&#xff0c;找数据分析岗位的同学一定要码住认真看。 想了解最新的面试动态、最新高频考点、技术交流的同学&#xff0c;可以文…

Windows和Linux访问不了GitHub的解决方法

一、Windows访问不了GitHub 问题描述 使用Windows访问GitHub时&#xff0c;出现如下情况&#xff0c;显示无法访问。 解决方案&#xff1a; 打开域名查询网站&#xff1a;https://tool.chinaz.com/dns 输入GitHub的域名&#xff0c;点击立即检测。 出现如下页面&#xff0c…

RK3399平台开发系列讲解(USB篇)BusHound 工具使用介绍

🚀返回专栏总目录 文章目录 一、BusHound简介二、BusHound的下载三、BusHound设备窗口四、BUSHound发送命令窗口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 BusHound软件是由美国perisoft公司研制的一种专用于PC机各种总线数据包监视和控制的开发工具软件,其名…

2024年学鸿蒙开发有前途吗?

随着科技的不断发展和智能设备的普及&#xff0c;鸿蒙系统作为华为自主研发的操作系统&#xff0c;正逐渐受到市场的关注。2024年&#xff0c;学鸿蒙开发是否有前途&#xff0c;成为了很多开发者和学生关心的问题。本文将从多个角度分析鸿蒙系统的发展前景&#xff0c;以及学习…

JavaScript入门分享

文章目录 一、JavaScript简介二、第一个JavaScript案例三、在浏览器中执行JavaScript代码四、JavaScript的输出方法五、JavaScript的语法六、JavaScript的数据类型七、JavaScript的定义变量/函数八、热门文章 一、JavaScript简介 JavaScript是一种高级编程语言&#xff0c;用于…

esxi配置NTP自动对时与手动对时

目录 背景解法配置NTP服务器立即与NTP服务器同步时间 附&#xff1a;几个常用的NTP服务器列表 背景 VMware ESXi 6.7运行了一段时间后偶然发现系统时间与标准时间有5分钟左右的差异&#xff0c;于是研究了下如何自动对时以及用命令行立即对时。 解法 配置NTP服务器 首先在管…

手把手教你使用MDK仿真调试

当今的嵌入式系统开发领域中&#xff0c;高效的调试工具对于工程师来说至关重要。它们能够极大地减少开发周期中的错误追踪时间&#xff0c;并加速产品的上市时间。MDK作为业界领先的嵌入式开发工具之一&#xff0c;其内置的调试功能被广大开发者所赞誉。这些功能不仅提供了对代…

PostgreSQL 是不是大小写敏感

如果你踩过 MySQL 的大坑的话就知道&#xff1a;MySQL 在 Windows 下不区分大小写&#xff0c;但在 Linux 下默认是区分大小写。 如果你稍加不注意就会出现在本机开发的程序运行一切正常&#xff0c;发布到服务器行就出现表名找不到的问题。 这是我们前一个项目遇到的巨大问题…

Python中函数的参数有哪些?

目录 ①必选参数 ②默认参数 ③可变参数 ④关键字参数 ⑤命名关键字参数 学习python函数部分的时候&#xff0c;发现除了正常定义的必选参数外&#xff0c;还使用默认参数、可变参数、关键字参数和命名关键字参数&#xff0c;在这里理清楚这些参数具体是怎么回事吧&#x…

nvm 配置淘宝镜像失效,以及安装node后 npm-v 无效

win11 nvm版本 1.1.4 和1.1.7和1.1.12&#xff08;目前最新版本24年 一月二十三日&#xff09; 以上nvm版本都会出现一下问题&#xff0c; 从https://github.com/coreybutler/nvm-windows/releases 下载nvm安装包如下图 傻瓜式安装后&#xff0c;不用去配置环境变量&#…

动态IP代理与静态IP代理:详细区别与比较全析

动态代理IP和静态代理IP在跨境业务中具有非常广泛的实用性&#xff0c;但仍然有非常多小白选手并不清楚什么场景适合用哪一类IP&#xff0c;哪一中代理IP类型更适合你&#xff1f;其实他们各有其优点和缺点&#xff0c;为了使您的网络营销、社媒推广、跨境电商运营、网络抓取尽…

C#用DateTime.DaysInMonth(Int32, Int32) 获取指定月的天数

目录 一、DateTime.DaysInMonth(Int32, Int32) 方法 二、实例 1.实例1 2.实例2 3.方法3 一、DateTime.DaysInMonth(Int32, Int32) 方法 返回指定年和月中的天数。 public static int DaysInMonth (int year, int month);参数 year Int32 年。month Int32 月&#…

「JavaSE」抽象类接口2

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 抽象类&接口2 &#x1f349;接口间的继承&#x1f349;接口的应用&#x1f349;总结 &#x1f349;接口间的继承 和类的继承…

Java--异常处理

文章目录 主要内容一.练习11.源代码代码如下&#xff08;示例&#xff09;: 2.结果 二.练习21.源代码代码如下&#xff08;示例&#xff09;: 2.结果 三.练习31.源代码代码如下&#xff08;示例&#xff09;: 2.结果 总结 主要内容 一.练习1 编写程序&#xff0c;定义一个 cir…

FRRouting学习(一) 配置日志文件

以配置isis event事件日志为例 1、在配置之前&#xff0c;/var/log/frr路径下是没有文件的&#xff1a; 2、在vtysh config之下输入&#xff1a;log file /var/log/frr/isisd.log debugging 后面的debugging表示日志级别&#xff0c;可以根据自己修改 3、配置好了之后&#xf…

力扣hot100 两两交换链表中的节点 双指针

Problem: 24. 两两交换链表中的节点 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( 1 ) O(1) O(1) Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { …

力扣hot100 环形链表 快慢指针 哈希 数学公式

Problem: 142. 环形链表 II 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( 1 ) O(1) O(1) /** /*** Definition for singly-linked list.* class ListNode {* int val;* …