算法训练day15Leetcode102二叉树层序遍历226翻转二叉树101对称二叉树

今天学习的文章和视频链接

https://www.bilibili.com/video/BV1ue4y1Y7Mf/?vd_source=8272bd48fee17396a4a1746c256ab0ae

102 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:输入:root = [1]
输出:[[1]]
示例 3:输入:root = []
输出:[]提示:树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

题目分析

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

acm模式代码

#include <iostream>
#include <vector>
#include <queue>
struct TreeNode {int val;TreeNode* left;TreeNode* right;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:std::vector<std::vector<int>> levelOrder(TreeNode* root) {std::queue<TreeNode*> que;std::vector<std::vector<int>> result;if (root != nullptr) que.push(root);while (!que.empty()) {int size = que.size();std::vector<int> vec;for (int i = 0; i < size; i++) {TreeNode* node = que.front();vec.push_back(node->val);que.pop();if(node->left) que.push(node->left);if(node->right) que.push(node->right);}result.push_back(vec);}return result;}
};int main() {// 创建一个简单的二叉树TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);Solution sol;std::vector<std::vector<int>> level_order = sol.levelOrder(root);// 打印层序遍历结果std::cout << "层序遍历:" << std::endl;for (const auto& level : level_order) {for (int val : level) {std::cout << val << " ";}std::cout << std::endl;}
}

226 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。示例 1:输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:输入:root = [2,1,3]
输出:[2,3,1]
示例 3:输入:root = []
输出:[]提示:树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100

题目分析

确定递归函数的参数和返回值
参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。

返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*。

TreeNode* invertTree(TreeNode* root)

确定终止条件
当前节点为空的时候,就返回

if (root == NULL) return root;

确定单层递归的逻辑
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);

acm模式代码

#include <iostream>
#include <algorithm>struct TreeNode {int val;TreeNode* left;TreeNode* right;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:TreeNode* invertTree(TreeNode* root) {if (root == nullptr) {if (root == nullptr) {return root;}}std::swap(root->left,root->right);invertTree(root->left);invertTree(root->right);return root;}
};void printTree(TreeNode* root) {if (root != nullptr) {std::cout << root->val << " ";printTree(root->left);printTree(root->right);}
}int main() {// 创建一个简单的二叉树TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);std::cout << "Original tree: ";printTree(root);std::cout << std::endl;Solution sol;root = sol.invertTree(root);std::cout << "Inverted tree: ";printTree(root);std::cout << std::endl;// 清理分配的内存delete root->left->left;delete root->left->right;delete root->left;delete root->right;delete root;return 0;
}

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进阶:你可以运用递归和迭代两种方法解决这个问题吗?

题目分析

首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

但都可以理解算是后序遍历,尽管已经不是严格上在一个树上进行遍历的后序遍历了。

其实后序也可以理解为是一种回溯,当然这是题外话,讲回溯的时候会重点讲的

递归法

递归三部曲

确定递归函数的参数和返回值
因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。

返回值自然是bool类型。

bool compare(TreeNode* left, TreeNode* right)

确定终止条件
要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)

左节点为空,右节点不为空,不对称,return false
左不为空,右为空,不对称 return false
左右都为空,对称,返回true
此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

左右都不为空,比较节点数值,不相同就return false
此时左右节点不为空,且数值也不相同的情况我们也处理了。

if (left == NULL && right != NULL) return false;
else if (left != NULL && right == NULL) return false;
else if (left == NULL && right == NULL) return true;
else if (left->val != right->val) return false; // 注意这里我没有使用else

确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
如果左右都对称就返回true ,有一侧不对称就返回false 。
代码如下:

bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
bool isSame = outside && inside;                    // 左子树:中、 右子树:中(逻辑处理)
return isSame;

acm 完整代码

#include <iostream>struct TreeNode {int val;TreeNode* left;TreeNode* right;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 compare(TreeNode* left, TreeNode* right) {if (left == nullptr && right != nullptr) return false;else if (left != nullptr && right == nullptr) return false;else if (left == nullptr && right == nullptr) return true;else if (left->val != right->val) return false;bool outside = compare(left->left, right->right);bool inside = compare(left->right, right->left);bool isSame = outside && inside;return isSame;}bool isSymmetric(TreeNode* root) {if (root == nullptr) return true;return compare(root->left, root->right);}
};int main() {// 创建一个简单的对称二叉树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);Solution sol;bool result = sol.isSymmetric(root);std::cout << "Is the tree symmetric? " << (result ? "Yes" : "No") << std::endl;// 清理分配的内存delete root->left->left;delete root->left->right;delete root->left;delete root->right->left;delete root->right->right;delete root->right;delete root;return 0;
}

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

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

相关文章

Oracle-数据库性能变慢问题分析

问题背景: 应用运维报障说最近两天业务数据入库和表查询都变得很慢&#xff0c;需要排查一下数据库的性能问题 问题分析&#xff1a; 登录到服务器上&#xff0c;通过TOP命令快速看了一下&#xff0c;服务器整体的CPU使用%usr不算特别高&#xff0c;但%wa IO等待很高&#xff…

MySQL加锁规则

项目编写涉及到数据持久化一般选择使用MySQL。由于时间原因&#xff0c;数据库使用我选择了无脑三板斧&#xff1a;1. 建立了索引加速查询、2. 关闭自动提交事务、3. 在需要确保原子性的数据库操作之间手动创建和提交事务。 这么一看&#xff0c;仿佛即使是实际开发也与你此前…

蓝桥杯单片机快速教程5——利用状态机思想编程

预习知识&#xff1a; &#xff08;1&#xff09;状态机理论 http://t.csdnimg.cn/lXwjw &#xff08;2&#xff09;基础视频 【蓝桥杯单片机保姆级教学】 https://www.bilibili.com/video/BV1h3411m7Aw/?p119&share_sourcecopy_web&vd_sourcec4fc67867c5218768e783d0…

什么是WhatsApp Business?WhatsApp和WhatsApp Business区别?

什么是WhatsApp Business&#xff1f; WhatsApp Business账号是Meta专为企业设计的WhatsApp账号。不同于消费者层次的应用&#xff0c;WhatsApp Business旨在为企业提供更好的服务支持&#xff0c;方便企业与消费者建立更好的双向沟通渠道。 WhatsApp和WhatsApp Business有什…

为什么有人说PMP是水证,它的含金量到底怎么样?

在我国大陆&#xff0c;有好多证书被商业化得太重了&#xff0c;甚至演变成了个人或一些公司摇钱的工具。所以有些证书受人吹捧它崛起的快&#xff0c;但是活不长&#xff0c;甚至“夭折”&#xff0c;比如以前微软系列的证书&#xff1b; 而PMP认证从国外引进大陆这么多年了&…

可行性研究报告范文模板(可直接套用)-word

1业务需求可行性分析 2技术可行性分析 2.1规范化原则 2.2高度的兼容性和可移植性 2.3人性化、适用性 2.4标准化统一设计原则 2.5先进安全可扩展性原则 3开发周期可行性分析 4人力资源可行性分析 5成本分析 6收益分析 7结论 软件开发全文档获取&#xff1a;软件项目…

[python]pyside6安装和在pycharm配置

安装命令&#xff1a; pip install PySide6 -i https://mirror.baidu.com/pypi/simple Pycharm配置Pyside6 打开Pycharm点击File -> Settings -> Tools -> External Tools&#xff0c;点击&#xff0b;。需要添加 Pyside6-Designer 、 Pyside6-UIC 和 Pyside6-rcc三…

突破界限:首个国产DeepSeek MoE的高效表现

前言 在人工智能技术的快速发展过程中&#xff0c;国产首个开源MoE&#xff08;Mixture of Experts&#xff09;大模型——DeepSeek MoE的推出&#xff0c;不仅标志着中国在全球AI领域的重大突破&#xff0c;而且在计算效率和模型性能上展现了显著的优势。这款160亿参数的模型…

初识Qt-无法解析的外部符号

跟着教程学习QT, 第一个对象树就出现bug&#xff0c;自己建立一个QPushButton的类&#xff0c; #ifndef MYPUSHBUTTON_H #define MYPUSHBUTTON_H #include <QPushButton> class MyPushButton:public QPushButton { Q_OBJECT public: MyPushButton(QWidget *parent)…

Vue3使用tinymce的配置和坑

一、安装依赖 下载安装依赖 yarn add tinymce -S; yarn add tinymce/tinymce-vue -S;下载中文语言包和静态文件 2.1 这一步网上都有&#xff0c;直接去官网下载语言包&#xff0c;将文件放在public/tinymce/langs中&#xff0c;这样打包后静态文件会被复制到打包后的目录中2.…

ECharts 多季度连续显示到一个图中。

效果图 二.相关option 以下option可以复制到 echarts的编辑器 进行查看修改 const site test1; const site2 test2;const qtrlyOption function (data: any, titleText: string): any {//获取最大值 。最大最小值的目的是&#xff1a;使左右里边的所有bar使用同一个指标let …

[HTML]Web前端开发技术12(HTML5、CSS3、JavaScript )——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

WebGIS招聘原来看重什么?整理了1300多份岗位得出来的干货!

之前给大家分享了一份boss直聘、猎聘和前程无忧上WebGIS相关的岗位汇总表&#xff1a; http://t.csdnimg.cn/35vn4 可以直接一键投递&#xff0c;需要的宝子记得后台找我。 今天给大家汇总了这些所有岗位的要求&#xff0c;包括学历、工作经验、城市、薪资以及技术要求等。 到…

DNS从入门到精通

DNS从入门到精通 Dns从入门到精通 DNS从入门到精通一、DNS原理二、企业高速缓存dns的搭建三、DNS相关名词解释四、权威DNS搭建编辑子配置文件&#xff08;主要写我们维护的域zone)开始解析 五、权威dns中的数据记录种类及应用编辑子配置文件&#xff08;主要写我们维护的域zone…

rman备份策略与RECLAIMABLE

在Oracle rman 需要keep 7days 时&#xff0c;report obsolete不能删除文件&#xff0c;但是如果Oracle已经备份到磁带上&#xff0c;RECLAIMABLE的空间Oracle内部可以自动释放的。 也就是说Oracle这是已经不能从磁盘回复&#xff0c;要磁带恢复复了 2023/12/24 10:35:31 …

js中的class类

目录 class构造函数方法原型方法访问器方法静态方法 继承super minxin关于多态 class 在ES6中之前如果我们想实现类只能通过原型链和构造函数的形式&#xff0c;不仅难以理解步骤也十分繁琐 在ES6中推出了class关键字&#xff0c;它可以在js中定一个类&#xff0c;通过new来实…

【极光系列】SpringBoot集成Mybatis

【极光系列】SpringBoot集成Mybatis 一.gitee地址 浅夏的猫 shawsongyue 直接下载可用 https://gitee.com/shawsongyue/aurora.git 二.mysql安装教程 详细参考我的另外一遍博客&#xff1a; https://blog.csdn.net/weixin_40736233/article/details/135582926?spm1001.201…

从物联网到数字孪生:智慧社区的未来之路

一、物联网在智慧社区中的应用与挑战 随着科技的飞速发展&#xff0c;物联网技术已经深入到我们生活的方方面面&#xff0c;尤其在智慧社区的建设中发挥着举足轻重的作用。物联网通过连接各种设备和系统&#xff0c;为社区居民提供了更便捷、高效的生活方式&#xff0c;同时也…

Hologres + Flink 流式湖仓建设

Hologres Flink 流式湖仓建设 1 Flink Hologres2 实时维表 Lookup 1 Flink Hologres holo在实时数仓领域非常受欢迎&#xff0c;一般搭配flinkhologres来做实时数仓&#xff0c;中间分层用holo&#xff0c;上下游一般依赖于holo的binlog来下发数据 2 实时维表 Lookup Holo…

微服务理解

分布式和微服务有什么区别 分布式是把一个集中式系统拆分成多个系统&#xff0c;每一个系统单独对外提供部分功能&#xff0c;整个分布式系统整体对外提供一整套服务。对于访问分布式系统的用户来说&#xff0c;感知上就像访问一台计算机一样. 而分布式架构的具体实现有很多种…