坚持刷题 |对称二叉树

文章目录

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

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

题目

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);
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scapy编程指南(基础概念)

Scapy编程指南&#xff08;基础概念&#xff09; Scapy是什么 Scapy是Python中一个非常强大的库&#xff0c;它专门用于处理、发送和捕获网络协议中的数据包&#xff0c;它允许开发人员通过Python代码构建、解析和发送自定义网络协议的数据包。Scapy提供了一种直观、灵活的方…

luffy商城项目(二)

路飞后端配置 二次封装response drf提供的Response对象&#xff0c;不能很方便的加入code和msg字段&#xff0c;自己封装一个Response类&#xff0c;以后都用我们自己封装的&#xff0c;方便咱们写code和msg 封装步骤&#xff1a; 1 在utils/common_response.py from rest_…

GitLab升级版本(任意用户密码重置漏洞CVE-2023-7028)

目录 前言漏洞分析影响范围查看自己的GitLab版本升级路程 升级过程13.1.1113.8.8 - 14.0.1214.3.614.9.5 - 16.1.6 前言 最近GitLab发了个紧急漏洞需要修复&#xff0c;ok接到命令立刻着手开始修复&#xff0c;在修复之前先大概了解一下这个漏洞是什么东西 漏洞分析 1、组件…

【立创EDA-PCB设计基础】6.布线铺铜实战及细节详解

前言&#xff1a;本文进行布线铺铜实战及详解布线铺铜的细节 在本专栏中【立创EDA-PCB设计基础】前面完成了布线铺铜前的设计规则的设置&#xff0c;接下来进行布线 布局原则是模块化布局&#xff08;优先布局好确定位置的器件&#xff0c;例如排针、接口、主控芯片&#xff…

《WebKit 技术内幕》学习之十一(2):多媒体

2 视频 2.1 HTML5视频 在HTML5规范定义中&#xff0c;Web开发者可以使用“video”元素来播放视频资源。视频中有个重要的问题就是视频编码格式&#xff0c;对此&#xff0c;目前标准中包含了三种编码格式&#xff0c;它们分别是Ogg、MPEG4和WebM。其中Ogg是由Xiph.org组织开…

(二)CarPlay集成开发之苹果的iAP协议

文章目录 概要协议格式鉴权流程CarPlay中的iAP2协议应用小结 概要 iAP2协议是由苹果公司定义的一种数据通信协议&#xff0c;主要用于苹果设备认证外设&#xff0c;以及与外设数据交换的一种协议 协议格式 协议格式一共分为三种类型&#xff0c;分别为握手包&#xff0c;链路…

「 典型安全漏洞系列 」06.路径遍历(Path Traversal)详解

引言&#xff1a;什么是路径遍历&#xff1f;如何进行路径遍历攻击并规避常见防御&#xff1f;如何防止路径遍历漏洞。 1. 简介 路径遍历&#xff08;Path Traversal&#xff09;是一种安全漏洞&#xff0c;也被称为目录遍历或目录穿越、文件路径遍历。它发生在应用程序未正确…

mac电脑安卓文件传输工具:Android File Transfer直装版

Android File Transfer&#xff08;AFT&#xff09;是一款用于在Mac操作系统上与Android设备之间传输文件。它允许用户将照片、音乐、视频和其他文件从他们的Android手机或平板电脑传输到Mac电脑&#xff0c;以及将文件从Mac上传到Android设备。 下载地址&#xff1a;https://w…

【立创EDA-PCB设计基础完结】7.DRC设计规则检查+优化与丝印调整+打样与PCB生产进度跟踪

前言&#xff1a;本文为PCB设计基础的最后一讲&#xff0c;在本专栏中【立创EDA-PCB设计基础】前面已经将所有网络布线铺铜好了&#xff0c;接下来进行DRC设计规则检查优化与丝印调整打样与PCB生产进度跟踪 目录 1.DRC设计规则检查 2.优化与丝印调整 1.过孔连接优化 2.泪滴…

如何做好一个信息系统项目经理,一个项目经理的个人体会和经验总结(四)

前言 说完了在 项目开发阶段 我的一些个人体会和经验总结&#xff0c;最后我们聊聊在 项目验收阶段 我们需要关注哪些方面的内容…… 项目验收阶段 系统开发告一段落后&#xff0c;就进入客户培训、系统验收阶段&#xff0c;这个阶段&#xff0c;我一般会注意以下几个问题&a…

NAT配置

目录 静态NAT配置配置抓包测试 动态NAT配置配置测试 Easy IP配置配置测试 静态NAT配置 配置 nat static global { global-address} inside {host-address } 命令用于创建静态NAT。 global参数用于配置外部公网地址。 inside参数用于配置内部私有地址。 AR1-NAT <Huawei&g…

Effective C++——关于重载赋值运算

令operator返回一个*this的引用 在重载,,*等运算符时&#xff0c;令其返回一个指向this的引用。 class MyClass {int* val; public:MyClass(int i) : val(new int(i)){}MyClass():val(new int(0)){}void print() {cout << *val << endl;}MyClass& operator(co…

基于SpringBoot Vue美食网站系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

Django入门,十分钟学会登录网页

我们假定你已经阅读了 安装 Django。你能知道 Django 已被安装&#xff0c;且安装的是哪个版本&#xff0c;通过在命令提示行输入命令 cmd黑窗口运行&#xff0c;不懂cmd百度一下 python -m django --version 如果没出现版本&#xff0c;就是没安装&#xff0c;那么用pip安装…

什么叫特征分解?

特征分解&#xff08;Eigenvalue Decomposition&#xff09;是将一个方阵分解为特征向量和特征值的过程。对于一个 nn 的方阵A&#xff0c;其特征向量&#xff08;Eigenvector&#xff09;v 和特征值&#xff08;Eigenvalue&#xff09; λ 满足以下关系&#xff1a; 这可以写…

vp9协议笔记

vp9协议笔记&#x1f4d2; 本文主要是对vp9协议的梳理&#xff0c;协议的细节参考官方文档&#xff1a;VP9协议链接&#xff08;需要加速器&#xff09; vp9协议笔记 vp9协议笔记&#x1f4d2;1. 视频编码概述2. 超级帧superframe&#xff08;sz&#xff09;&#xff1a;2. fr…

【码农新闻】浏览器上有趣的 Console 命令,VSCode 插件 FreeWindow......

目录 【码农新闻】浏览器上有趣的 Console 命令,VSCode 插件 FreeWindow...... 浏览器上有趣的 Console 命令VSCode 插件 FreeWindow拖拽竟然还能这样玩!阮一峰 ES6 教程总结学习网站总结与整理买临期食品的年轻人,在向“吃喝内卷”低头文章所属专区 码农新闻 欢迎各位编程大…

100T数据存进服务器分几步?

大家好&#xff0c;我是豆小匠。 这期来聊聊数据存储相关的问题&#xff0c;包括&#xff1a; 容量评估。技术选型。容灾处理。 另外&#xff0c;文末赠送免费定制红包封面哦&#xff01; 1. 容量评估 通过对容量&性能的评估&#xff0c;可以把业务需求转化成技术语言描…

Mysql数据库DQL查询语言之表连接(联合查询)

表连接 关系字段&#xff1a;两表中有关联关系的字段 \关系字段&#xff1a;两表之间存在关系的字段 什么是表连接&#xff1f; 当我们的查询结果需要从多张表中获取时&#xff0c;此时应该让表之间建立连接&#xff0c;同时获取数据 内连接 特点&#xff1a;同时对连接双方做…

SpringBoot集成mybatis时idea控制台中文乱码问题解决

在application.yml中配置好映射文件打印数据库日志文件时&#xff0c;控制台出现乱码的情况解决如下 问题 在执行查询操作的时候&#xff0c;查询时可以查看是没有问题的&#xff0c;但是控制台乱码了 解决 在File-Setting-Editor-File Encodings中设置如图所示就可以了 现在…