【算法与数据结构】101、LeetCode对称二叉树
文章目录
- 一、题目
- 二、递归法
- 三、迭代法
- 三、完整代码
所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。
一、题目


二、递归法
思路分析:这道题目标就是要对比左右两半的树是否对称,因此对比不是左右节点是否相等,而是根节点的左子树和右子树是否相等。刚开始笔者想到的是做层序遍历,然后判断每层的值是否前后对称,但是由于层序遍历当中空节点是不显示的,因此例二也会判成对称树。为此我们可以把空节点也显示出来,但是这样一来遍历的节点数量要大于等于树本身非空节点的数量,徒增计算量。经过一番思考,还是想用递归法实现。程序当中我们对比两个结点是否相等,一共有四种情况。其实还有一种情况,就是节点1的值等于节点2的值,这部分判断包含在cmpTree函数的递归语句return当中,如果出现第五种情况,最终会以第一种情况的形式返回。
- 1.节点1、节点2为空,对称,返回true;
- 2.节点1为空、节点2不为空, 不对称,返回false;
- 3.节点1不为空、节点2为空, 不对称,返回false;
- 4.节点1不为空、节点2不为空, 但值不相等,不对称,返回false;
程序如下:
class Solution {
public:// 递归法bool cmpTree(TreeNode* node1, TreeNode* node2) {if (node1 == NULL && node2 == NULL) return true; // 二者均为空节点if (node1 == NULL || node2 == NULL || node1->val != node2->val) return false; // 其他三种情况return cmpTree(node1->left, node2->right) && cmpTree(node1->right, node2->left);}bool isSymmetric(TreeNode* root) {if (root == NULL) return true;return cmpTree(root->left, root->right);}
};
三、迭代法
思路分析:迭代法使用了队列,先将根节点的左右节点压入队中,然后判断语句的思路和递归当中一致,最后再将要比较的节点按顺序入队,注意节点1的左节点和节点2的右节点比较,节点1的右节点和节点2的左节点比较。
class Solution2 {
public:// 迭代法bool isSymmetric(TreeNode* root) {if (!root) return true; // 根节点为空,直接返回queue<TreeNode*> que;que.push(root->left);que.push(root->right);while (!que.empty()) {TreeNode* node1 = que.front(); que.pop();TreeNode* node2 = que.front();que.pop();if (!node1 && !node2) continue;if (!node1 || !node2 || node1->val != node2->val) return false;que.push(node1->left);que.push(node2->right);que.push(node1->right);que.push(node2->left);}return true;}
};
三、完整代码
# include <iostream>
# include <vector>
# include <queue>
# include <string>
# include <stack>
using namespace std;// 树节点定义
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 {
public:// 递归法bool cmpTree(TreeNode* node1, TreeNode* node2) {if (node1 == NULL && node2 == NULL) return true; // 二者均为空节点if (node1 == NULL || node2 == NULL || node1->val != node2->val) return false; // 其他三种情况return cmpTree(node1->left, node2->right) && cmpTree(node1->right, node2->left);}bool isSymmetric(TreeNode* root) {if (root == NULL) return true;return cmpTree(root->left, root->right);}
};class Solution2 {
public:// 迭代法bool isSymmetric(TreeNode* root) {if (!root) return true; // 根节点为空,直接返回queue<TreeNode*> que;que.push(root->left);que.push(root->right);while (!que.empty()) {TreeNode* node1 = que.front(); que.pop();TreeNode* node2 = que.front();que.pop();if (!node1 && !node2) continue;if (!node1 || !node2 || node1->val != node2->val) return false;que.push(node1->left);que.push(node2->right);que.push(node1->right);que.push(node2->left);}return true;}
};void my_print2(vector<vector<int>>& v, string str) {cout << str << endl;for (vector<vector<int>>::iterator vit = v.begin(); vit < v.end(); ++vit) {for (vector<int>::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {cout << *it << ' ';}cout << endl;}
}// 前序遍历递归法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {if (t[0] == "NULL" || !t.size()) return; // 退出条件else {node = new TreeNode(stoi(t[0].c_str())); // 中t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->left); // 左t.assign(t.begin() + 1, t.end());Tree_Generator(t, node->right); // 右}
}vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size(); // size必须固定, que.size()是不断变化的vector<int> vec;for (int i = 0; i < size; ++i) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left); // 空节点不入队if (node->right) que.push(node->right);}result.push_back(vec);}return result;
}int main()
{vector<string> t = { "1", "2", "3", "NULL", "NULL", "4", "NULL", "NULL", "2", "4", "NULL", "NULL", "3", "NULL", "NULL" }; // 前序遍历//vector<string> t = { "1", "2", "NULL", "3", "NULL", "NULL", "2", "NULL", "3", "NULL", "NULL" }; // 前序遍历TreeNode* root = new TreeNode();Tree_Generator(t, root);vector<vector<int>> tree = levelOrder(root);my_print2(tree, "目标树:");Solution2 s1;bool result = s1.isSymmetric(root);if (result) cout << "对称树" << endl;else cout << "非对称树" << endl;system("pause");return 0;
}
end
相关文章:
【算法与数据结构】101、LeetCode对称二叉树
文章目录 一、题目二、递归法三、迭代法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、递归法 思路分析:这道题目标就是要对比左右两半的树是否对称,因此对比不是左右节点是否相等&…...
【N32L40X】学习笔记04-gpio中断库
gpio中断 该函数库的目的就是在统一的地方配置,将配置的不同项放置在一个结构体内部使用一个枚举来定义一个的别名 NVIC 寄存器 NVIC 相关的寄存器定义了可以在 core_cm4.h 文件中找到。我们直接通过程序的定义来分 析 NVIC 相关的寄存器,其定义如下…...
Godot 4 着色器 - Shader调试
我之前用OpenCV进行图像相关处理,觉得已经很不错,结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现,着色器更上一层楼,原来这是入了GPU的坑 Shader编程限制很多,各种不支持,看在它性能不错功能炫…...
liunx时间慢几分钟,定时更新系统时间
#!/bin/sh hwclock --hctosys echo "执行成功" 定时5分钟执行一次...
C# 委托详解
一.委托的概念 C#中委托也叫代理,委托提供了后期绑定机制(官方解释),功能类似于C中的函数指针,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。 二.委托的用法…...
chatGPT 学习分享:内含PPT分享下载
InstructGPT论文地址: Training language models to follow instructions with human feedbackchatGPT地址:openAI个人整理的PPT(可编辑),下载地址:chatGPT学习分享PPT...
使用CRM进行数据分析的四大好处
使用CRM数据分析系统够帮助企业更好地了解客户需求和行为习惯,提供个性化的服务,从而提高客户满意度和忠诚度。使用CRM数据分析系统可以为企业带来一些好处,包括提高客户洞察力、加强营销策略、提高运营效率等。 1.提高客户洞察力:…...
Excel“牛人”变现方案参考
有几种方式可以通过Excel技能实现变现: 1. 提供Excel咨询和培训服务:如果你对Excel非常熟悉,你可以提供咨询和培训服务,帮助他人解决Excel使用中的问题或提高他们的Excel技能。 2. 制作和销售Excel模板:你可以根据市…...
vscode和jetbrains IDEA添加免费的gpt代码生成插件
vscode和jetbrains IDEA添加免费的gpt代码生成插件 VSCODE添加代码智能生成插件 一、打开vscode添加扩展 打开vscode,点击扩展,搜索 aws toolkit 二、连接到AWS 如图,选择添加connectiong to aws 选择 Sign up or Sign in …...
【C#】医学实验室云LIS检验信息系统源码 采用B/S架构
基于B/S架构的医学实验室云LIS检验信息系统,整个系统的运行基于WEB层面,只需要在对应的工作台安装一个浏览器软件有外网即可访问,技术架构:Asp.NET CORE 3.1 MVC SQLserver Redis等。 一、系统概况 本系统是将各种生化、免疫、…...
linux:AWS LightSail 设置虚拟内存
参考: https://www.cnblogs.com/fallin/p/13186236.html 总结: #2G的swap文件 sudo dd if/dev/zero of/swapfile bs1M count2048 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile sudo echo /swapfile none swap defaults 0 0 &g…...
“华为杯”研究生数学建模竞赛2016年-【华为杯】E题:粮食最低收购价问题研究
目录 摘 要: 第 1 章 前 言 1.1 研究的目的与意义 1.2 文献综述...
idea项目依赖全部找不到
目录 1,出错现象2,解决3,其他尝试 1,出错现象 很久没打开的Java项目,打开之后大部分依赖都找不到,出现了所有的含有import语句的文件都会报错和一些注解报红报错,但pom文件中改依赖是确实被引入…...
自动驾驶数据标注有哪些?
自动驾驶汽车:人工智能(AI)的焦点 人工智能驱动汽车解决方案的市场规模预计到 2025年将增长十倍以上,提升车内体验的商机领域以及 AI 模型的无偏见训练数据的重要性。在本篇中,我们将介绍车外体验的关键组成部分,以及自动驾驶数据…...
ChatGPT:人工智能语言模型的巅峰之作
一、 ChatGPT 的前世今生 ChatGPT 是 GPT(Generative Pre-trained Transformer)系列模型的最新成员,其前身 GPT-3 在推出后引起了广泛关注。OpenAI 团队不断优化和训练,终于推出了 ChatGPT,这一最先进的语言模型&#…...
【unity之IMGUI实践】敌方逻辑封装实现【六】
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:uni…...
llvm向用户抛出warning、error信息
1、抛出error信息并终止程序 使用DiagnosticInfoUnsupported可以向用户抛出error信息并且终止程序,效果如同report_fatal_error、Error。后端用法如下: void xxxx::reportErrorMsg(const MachineFunction &MF)const {const Function &F MF.ge…...
微服务学习笔记-----Nacos安装教程(Windows和Linux版本)
Nacos安装教程 Nacos安装指南1.Windows安装1.1.下载安装包1.2.解压1.3.端口配置1.4.启动1.5.访问 2.Linux安装2.1.安装JDK2.2.上传安装包2.3.解压2.4.端口配置2.5.启动 3.Nacos的依赖 Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的Git…...
程序员面试系列,docker常见面试题
原文链接 什么是Docker?它的主要作用是什么?Docker和虚拟机之间有什么区别?Docker的主要组件有哪些?Docker镜像和容器的区别是什么?如何构建Docker镜像?请简要描述构建过程。如何创建和启动一个Docker容器…...
Linux centos7.x系统将/home磁盘分配给/
1.解除挂载并删除/home卷 umount /home如果出现以下报错 : 可以使用以下命令查看哪些进程在占用 fuser -mv /home杀死这些进程就行 kill -9 进程号然后再执行umount /home就可以成功了 , 同时执行以下命令把逻辑卷删除了 lvremove /dev/centos/home…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
