力扣日记11.25-【二叉树篇】对称二叉树

力扣日记:【二叉树篇】对称二叉树

日期:2023.11.25
参考:代码随想录、力扣

101. 对称二叉树

题目描述

难度:简单

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

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

题解

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
#define SOLUTION 1
public:
#if SOLUTION == 0bool isSymmetric(TreeNode* root) {/* // 错误的做法// 示例1:前:1234243, 中:3241423, 后:3424321,层:1223443// 示例2:中:12323,层:12233// 层序遍历不行,只能中序遍历// 使用栈,元素先进栈,遇到相同的则弹出// 还是不能用值来判断是否对称....如果树上节点的值都是相等的,那就无法判断了...stack<int> st_check;  // 用来判断// 中序遍历:左中右// 对于中序遍历,访问和处理并不是同步进行的。而是先访问到最底层的左节点,再开始处理(入栈判断)// 使用 cur 指针 先进行访问(遍历)// if (root == NULL) return true;stack<TreeNode*> st;    // 用来遍历TreeNode* cur = root;while (cur != NULL || !st.empty()) {if (cur != NULL) { // 指针访问节点,先遍历到最底层st.push(cur);   // 将cur入栈cur = cur->left;    // 左} else { // 处理cur = st.top();   // 中 (处理:放入result数组)st.pop();if (cur != root) {  // 根节点不入栈判断if (st_check.empty() || st_check.top() != cur->val) st_check.push(cur->val);    // 空或不相等则入栈else st_check.pop();    // 相同则弹出}cur = cur->right;   // 右 (如果右节点不为空,则在下次循环把右节点入栈;否则从栈中弹出顶部节点)}}return st_check.empty(); */}
#elif SOLUTION == 1     // 递归遍历/*思路:判断二叉树是否对称 -> 通过判断二叉树能否左右翻转分别比较外侧与内侧是否相等,即左节点的外侧(左孩子)需与对应右节点的外侧(右孩子)相等,内测同理采用的遍历方式为后序遍历 -> 后序:左右中 -> 在左右子树都判断好是否能左右翻转后,再将信息传递到父节点(中),中节点作为左孩子或右孩子又继续向上传递*/bool compare(TreeNode* left, TreeNode* right) { // 递归三要素1:参数与返回值:参数为当前层的左节点和对应右节点,返回值为两者的子树能否相互翻转(注意是子树,不包括自身,尽管只有当左和对应右节点相等才有继续比较的必要)// 递归三要素2:终止条件:// 1) 左右都为空:返回trueif (left == NULL && right == NULL)  return true;// 2) 左为空右不为空 或 左不为空右为空:返回falseelse if ((left != NULL && right == NULL) || (left == NULL && right != NULL))    return false;// 3) 左右不为空且左右值不相等else if (left->val != right->val)   return false;// 递归三要素3:处理逻辑:如果左右值相等,则递归向下判断else {                                                  // 由此可见:左右子树均为后序遍历// 外侧:bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右// 内侧:bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左// 将外侧内侧的比较结果向上传递(给中节点)bool isSame = outside && inside;                    // 左子树:中、 右子树:中 (逻辑处理)return isSame; // 当外侧和内侧的子节点都分别相等,则当前left和right的子树是可以翻转的}}bool isSymmetric(TreeNode* root) {return compare(root->left, root->right);}#elif SOLUTION == 2 // 迭代法(队列)bool isSymmetric(TreeNode* root) {// 思路:// 遍历:将左侧节点和对应右侧节点成对放入队列;// 处理:再在弹出时成对弹出比较是否相等,相等则继续遍历子节点,否则终止queue<TreeNode*> q;if (root != nullptr) {  // 先把根节点的左右节点放入队列q.push(root->left);q.push(root->right);}while (!q.empty()) {// 成对弹出TreeNode* leftSide = q.front();     q.pop();TreeNode* rightSide = q.front();    q.pop();// 比较if (!leftSide && !rightSide) continue; // 左右都为空(没有子节点,则继续弹出)// 左右有一个为空 或 左右都不为空但不相等,则肯定不对称,返回falseelse if (!leftSide || !rightSide || (leftSide->val != rightSide->val)) return false;// 如果相等,则继续遍历,将子节点入队列q.push(leftSide->left);q.push(rightSide->right); // 注意要成对:左的左 与 右的右q.push(leftSide->right);q.push(rightSide->left);    // 左的右 与 右的左}return true;}
#elif SOLUTION == 3 // 迭代法(栈)bool isSymmetric(TreeNode* root) {// 思路与队列类似,也是成对入栈、成对弹出、成对比较(队列更好理解……)stack<TreeNode*> st;if (root != nullptr) {  // 先把根节点的左右节点放入队列st.push(root->left);st.push(root->right);}while (!st.empty()) {// 成对弹出TreeNode* rightSide = st.top();  st.pop();TreeNode* leftSide = st.top();   st.pop();     // 比较if (!leftSide && !rightSide) continue; // 左右都为空(没有子节点,则继续弹出)// 左右有一个为空 或 左右都不为空但不相等,则肯定不对称,返回falseelse if (!leftSide || !rightSide || (leftSide->val != rightSide->val)) return false;// 如果相等,则继续遍历,将子节点入队列st.push(leftSide->left);st.push(rightSide->right); // 注意要成对:左的左 与 右的右st.push(leftSide->right);st.push(rightSide->left);    // 左的右 与 右的左}return true;}
#endif
};

复杂度

时间复杂度:
空间复杂度:

思路总结

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

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

相关文章

Blender 连续 5 天遭受大规模 DDoS 攻击

Blender 发布公告指出&#xff0c;在2023年11月18日至23日期间&#xff0c;blender.org 网站遭受了持续的分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;攻击者通过不断发送请求导致服务器超载&#xff0c;使网站运营严重中断。此次攻击涉及数百个 IP 地址的僵尸…

ATK-ESP8266 WIFI模块串口通信通用实现方案

ATK-ESP8266 WIFI模块是一种常用的无线模块&#xff0c;它可以通过串口与外部设备进行通信&#xff0c;实现数据的收发和控制。本文将介绍一种通用的实现方案&#xff0c;帮助您在项目中使用ATK-ESP8266 WIFI模块进行串口通信。 【方案概述】 这个通用实现方案涵盖了ATK-ESP82…

算法-技巧-中等-颜色分类

记录一下算法题的学习12 颜色分类 题目&#xff1a;给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝…

Android 相机库CameraView源码解析 (二) : 拍照

1. 前言 这段时间&#xff0c;在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位&#xff0c;在项目前期&#xff0c;的确为我们节省了不少时间。 但随着项目持续深入&#xff0c;对于CameraView的使用进入深水区&#xff0c;逐…

WordPress无需插件禁用WP生成1536×1536和2048×2048尺寸图片

我们在使用WordPress上传图片媒体文件的时候&#xff0c;是不是看到媒体库中有15361536和20482048的图片文件&#xff0c;当然这么大的文件会占用我们的服务器空间&#xff0c;如何禁止掉呢&#xff1f; function remove_default_image_sizes( $sizes) {unset( $sizes[1536x15…

spring-webmvc练习-日程管理-访问后端展示列表数据

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/schedule.js import request from "../util/request.js";export let getSchedu…

[架构之路-253]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 结构化设计的主要评估指标:高内聚(模块内部)、低耦合(模块之间)的含义

目录 前言&#xff1a; 一、软件工程中的软件设计种类&#xff1a;根据宏观到微观分 &#xff08;1&#xff09;软件架构设计&#xff08;层次划分、模块划分、职责分工&#xff09;&#xff1a; &#xff08;2&#xff09;软件高层设计、概要设计&#xff08;功能模块的接…

【c++随笔14】虚函数表

【c随笔14】虚函数表 一、虚函数表&#xff08;Virtual Function Table&#xff09;1、定义2、查看虚函数表2.1、 问题&#xff1a;三种类型&#xff0c;包含一个int类型的class、一个int类型的变量、int类型的指针&#xff1a;这三个大小分别是多少呢&#xff1f;2.2、怎么发现…

IT问题解答类型网站源码

问答网是一款为IT工程师提供的问答平台&#xff0c;旨在帮助用户在线获取专业知识和相关问题的答案。在问答网&#xff0c;用户可以轻松找到其他人的问答问题&#xff0c;并在这里寻求解答。如果您有任何想要解决的问题&#xff0c;都可以在此发布问题并得到其他同行的解答。 …

CSS之弹性盒子Flexible Box

我想大家在做布局的时候&#xff0c;没接触flex布局之前&#xff0c;大家都是用浮动来布局的&#xff0c;但现在我们接触了flex布局之后&#xff0c;我只能说&#xff1a;“真香”。让我为大家介绍一下弹性盒子模型吧&#xff01; Flexible Box 弹性盒子 在我们使用弹性盒子时&…

【算法】链表-20231127

这里写目录标题 一、面试题 02.02. 返回倒数第 k 个节点二、82. 删除排序链表中的重复元素 II三、141. 环形链表 一、面试题 02.02. 返回倒数第 k 个节点 提示 简单 130 相关企业 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&#xff1a;本…

Linux(8):BASH

硬件、核心与 Shell 操作系统其实是一组软件&#xff0c;由于这组软件在控制整个硬件与管理系统的活动监测&#xff0c;如果这组软件能被用户随意的操作&#xff0c;若使用者应用不当&#xff0c;将会使得整个系统崩溃。因为操作系统管理的就是整个硬件功能。 应用程序在最外层…

前端(HTML + CSS + JS)

文章目录 一、HTML1. 概念&#xff08;1&#xff09;HTML 文件基本结构&#xff08;2&#xff09;HTML代码框架 2. 、HTML常见标签 二、CSS1. CSS基本语法规范2. 用法&#xff08;1&#xff09; 引用方式&#xff08;2&#xff09;选择器&#xff08;3&#xff09;常用元素属性…

NX二次开发UF_CURVE_ask_trim 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_trim Defined in: uf_curve.h int UF_CURVE_ask_trim(tag_t trim_feature, UF_CURVE_trim_p_t trim_info ) overview 概述 Retrieve the current parameters of an a…

利用STM32和MFRC522 IC实现智能卡的读取和数据存储

利用STM32微控制器和MFRC522 RFID读写器芯片&#xff0c;可以实现智能卡的读取和数据存储功能。智能卡是一种集成了RFID技术和存储芯片的卡片&#xff0c;它可以用于身份验证、门禁控制、支付系统等应用场景。下面将介绍如何使用STM32和MFRC522芯片进行智能卡的读取和数据存储&…

3.OpenResty系列之Nginx反向代理

1. Nginx简介 Nginx (engine x) 是一款轻量级的 Web 服务器 、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器 什么是反向代理&#xff1f; 反向代理&#xff08;Reverse Proxy&#xff09;方式是指以代理服务器来接受 internet 上的连接请求&#x…

4面试题--数据库(补充)

隔离性问题 若不考虑隔离性则会出现以下问题 1. 脏读&#xff1a;指⼀个事务在处理数据的过程中&#xff0c;读取到另⼀个 未提交 事务的数据 2. 不可重复读&#xff1a;指对于数据库中的某个数据&#xff08;同⼀个数据项&#xff09;&#xff0c;⼀个事务内的多次查询却…

docker打包前端镜像

文章目录 一、构建镜像二、查看本地镜像三、启动容器四、查看启动的容器五、保存镜像六、读取镜像七、创建镜像八、最后 docker官网 一、构建镜像 -t是给镜像命名&#xff0c;.(点)是基于当前目录的Dockerfile来构建镜像 docker build -t image_web .二、查看本地镜像 docke…

使用echars实现数据可视化

生活随笔 展翅飞翔之际 请下定决心不再回头 echars实现数据可视化 在搭建后台页面时&#xff0c;可能会遇到很多的表格&#xff0c;但有时表格所展现的数据并不能直观的体现出当前用户的宏观信息&#xff0c;所以就可以引入一个新的表格插件——echars 快速上手 - Handbook…

某软件商店app抓包分析与sign加密算法实现

文章目录 1. 写在前面2. 抓包配置3. 抓包分析4. 接口测试5. sign加密算法6. 数据效果展示 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】…