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

二、解法
思路分析:这道题的思路很简单,本质上就是遍历每一个节点,然后交换左右节点。我们可以用前中后遍历或者是层次遍历法来做,参考这两篇文章,【算法与数据结构】144、94、145LeetCode二叉树的前中后遍历(递归法、迭代法)和【算法和数据结构】102、LeetCode二叉树的层序遍历。交换函数可以用库函数也可以自己写一个my_sawp()函数。
my_sawp()函数如下:
void my_swap(TreeNode* &root) {TreeNode* node = root->left;root->left = root->right;root->right = node;
}
迭代法前序遍历程序如下:
class Solution1 {
public:// 迭代法,前序遍历TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top(); // 中st.pop();swap(node->left, node->right);if (node->right) st.push(node->right); // 右if (node->left) st.push(node->left); // 左}return root;}
};
前序遍历,统一代码风格迭代写法:
class Solution2 {
public:// 前序遍历,统一代码风格迭代写法TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) { st.pop();if (node->right) st.push(node->right); // 右if (node->left) st.push(node->left); // 左st.push(node); // 中st.push(NULL);}else {st.pop();node = st.top();st.pop();swap(node->left, node->right);}}return root;}
};
递归法程序如下:
class Solution3 {
public:// 递归法TreeNode* invertTree(TreeNode* root) {if (root == NULL) return root;swap(root->left, root->right);invertTree(root->left);invertTree(root->right);return root;}
};
层序遍历法程序如下:
class Solution4 {
public:// 层序遍历法TreeNode* invertTree(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()是不断变化的for (int i = 0; i < size; ++i) {TreeNode* node = que.front();swap(node->left, node->right);que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return root;}
};
三、完整代码
# 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) {}
};void my_swap(TreeNode*& root) {TreeNode* node = root->left;root->left = root->right;root->right = node;
}class Solution1 {
public:// 迭代法,前序遍历TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top(); // 中st.pop();swap(node->left, node->right);if (node->right) st.push(node->right); // 右if (node->left) st.push(node->left); // 左}return root;}
};class Solution2 {
public:// 前序遍历,统一代码风格迭代写法TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) { st.pop();if (node->right) st.push(node->right); // 右if (node->left) st.push(node->left); // 左st.push(node); // 中st.push(NULL);}else {st.pop();node = st.top();st.pop();swap(node->left, node->right);}}return root;}
};class Solution3 {
public:// 递归法TreeNode* invertTree(TreeNode* root) {if (root == NULL) return root;swap(root->left, root->right);invertTree(root->left);invertTree(root->right);return root;}
};class Solution4 {
public:// 层序遍历法TreeNode* invertTree(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()是不断变化的for (int i = 0; i < size; ++i) {TreeNode* node = que.front();swap(node->left, node->right);que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return root;}
};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 = { "4", "2", "1", "NULL", "NULL", "3", "NULL", "NULL", "7", "6", "NULL", "NULL", "9", "NULL", "NULL" }; // 前序遍历TreeNode* root = new TreeNode();Tree_Generator(t, root);vector<vector<int>> tree = levelOrder(root);my_print2(tree, "目标树:");Solution2 s1;root = s1.invertTree(root);tree = levelOrder(root);my_print2(tree, "翻转后:");system("pause");return 0;
}
end
相关文章:
【算法与数据结构】226、LeetCode翻转二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:这道题的思路很简单,本质上就是遍历每一个节点,然后交换左右节点。我们可以用前…...
metaRTC6.0 new feature (一)
概要 metaRTC6.0社区版最新版是6.0.212,标准版最新版本是6.0.276,企业版基础版最新版本是6.0.362,在企业版和标准版新增了一些实用功能模块,文件数字证书模块将并入社区版。 New Feature rtsp协议支持 新增rtsp协议࿰…...
聊天机器人如何增加电子商务销售额
聊天机器人和自动化对企业和客户来说都是福音。自动对话和聊天机器人(以下统称为“自动化”)通过自动回答问题或分配会话信息来帮助用户浏览品牌网站或电商商店。即时答案对客户来说非常有用,使用自动化也可以让原本与客户聊天的客服员工专注…...
stm32 IIC通信
文章目录 IIC 通信一、硬件电路二、IIC时序基本单元三、IIC时序1.指定地址写2.当前地址读3.指定地址读 IIC 通信 IIC总线是一种通用数据总线,有两根通信线(SCL(串行时钟总线),SDA(串行数据总线))。 特点:同…...
Elasticsearch监控工具Cerebro安装
Elasticsearch监控工具Cerebro安装 1、在windwos下的安装 1.1 下载安装包 https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.zip 1.2 解压 1.3 修改配置文件 如果需要修改相关信息,编辑C:\zsxsoftware\cerebro-0.9.4\conf\applica…...
RTOS 低功耗设计原理及实现
RTOS 低功耗设计原理及实现 文章目录 RTOS 低功耗设计原理及实现👨🏫前言👨🔬Tickless Idle Mode 的原理及实现👨🚀Tickless Idle Mode 的软件设计原理👨💻Tickless Idle Mo…...
PaddleOCR C++编译出错解决方案
文章目录 前言一、环境准备1、主要环境2、源码下载3、C推理库下载 二、报错信息1.静态库调用错误2.ld returned 1 exit status 总结 前言 最近,想尝试下PaddleOCR的C推理,但是过程不如人所愿,除了很多问题,这里捡重点的说下吧&…...
89、简述RabbitMQ的架构设计
简述RabbitMQ的架构设计 BrokerQueueExchangeRoutingKeyBinding信道架构设计图Broker RabbitMQ的服务节点 Queue 队列,是RabbitMQ的内部对象,用于存储消息。RabbitMQ中消息只能存储在队列中。生产者投递消息到队列,消费者从队列中获取消息并消费。多个消费者可以订阅同一…...
63 | 图像处理
文章目录 Python图像处理什么是图像处理?Python图像处理库安装Pillow库加载和显示图像调整图像大小裁剪图像调整图像亮度、对比度和色彩平衡应用滤镜练习题Python图像处理 什么是图像处理? 图像处理是指使用计算机算法来改变图像的外观或特征。它可以用于许多不同的应用程序…...
Stable Diffusion - 扩展 Roop 换脸 (Face Swapping) 插件的配置与使用
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/131856141 官网:GitHub - roop,参考论文:RobustSwap: A Simple yet Robust Face Swapping Model against Attr…...
opencv实现替换证件照颜色
程序可以实现蓝色底片变为红色底片(但有点小bug) 修改自:opencv:HSV颜色模型_opencv hsv_君浪的博客-CSDN博客 相关文章:OpenCV Mat数据类型指针ptr的使用_cv::mat ptr_AoboSir的博客-CSDN博客 【OpenCV】HSV颜色识…...
Elasticsearch【全文检索、倒排索引、应用场景、对比Solr、数据结构】(一)-全面详解(学习总结---从入门到深化)
目录 Elasticsearch介绍_全文检索 Elasticsearch介绍_倒排索引 Elasticsearch介绍_Elasticsearch的出现 Elasticsearch介绍_Elasticsearch应用场景 Elasticsearch介绍_Elasticsearch对比Solr Elasticsearch介绍_Elasticsearch数据结构 Elasticsearch介绍_全文检索 Elasti…...
了解 3DS MAX 3D摄像机跟踪设置:第 2 部分
推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 转到合成>新合成以创建新合成。 将“宽度”和“高度”值分别设置为 1280 和 720。将帧速率设置为 25,将持续时间设置为 12 秒。单…...
MySQL 判断 JSON 数组是否相等
文章目录 1.问题2.使用 JSON_CONTAINS 与 JSON_LENGTH参考文献 1.问题 JSON(JavaScript Object Notation)是流行的互联网应用服务之间的数据交换格式。 MySQL 从 5.7 版本开始支持 RFC 7159 定义的 JSON 规范,主要有 JSON 对象 和 JSON 数组…...
uni-app个人中心
一. 介绍uni-app: uni-app 是基于Vue.js框架开发的一个跨平台移动应用开发框架,可以同时支持多个平台(如iOS、Android、Web等)的应用开发。采用了统一的语法和组件规范,可以大大简化跨平台开发的工作,提高…...
只需3步,使用Stable Diffusion无限生产AI数字人视频
效果演示 先看效果,感兴趣的可以继续读下去。 没有找到可以上传视频的地方,大家打开这个网盘链接观看:https://www.aliyundrive.com/s/CRBm5NL3xAE 基本方法 搞一张照片,搞一段语音,合成照片和语音,同…...
Mysql执行计划字段解释
文章目录 一、前言二、如何查看执行计划三、执行计划各字段解释四、select_type4.1、SIMPLE(简单查询)4.1.1、简单的单表查询4.1.2、多表连接查询 4.2、PRIMARY(主查询)4.2.1、包含复杂子查询的外层查询4.2.2、UNION语句中的第一个…...
Linux -- 线程
文章目录 1. 线程概念1.1 概念1.2 理解(Linux OS角度)1.3 见一见 2. 线程优缺点3. 线程使用3.1 认识线程库3.2 使用3.2.1 线程创建3.2.2 线程等待3.2.3 线程退出3.2.4 线程取消3.2.5 获取线程id3.2.6 线程分离 3.3 理解线程库3.4 证明线程栈3.5 线程局部…...
Android:实时更新时间
心想着也就是更新精确到分钟,不用精确到秒,定时器就没有必要,系统是有广播Intent.ACTION_TIME_TICK可以直接用 动态注册广播 主方法里面调用一下 //要先设置一下当前时间,不然刷新时间会等到1分钟后再刷新 tv_HM.setText(getHM…...
24 鼠标常用事件
鼠标进入:enterEvent鼠标离开:leaveEvent鼠标按下:mousePressEvent鼠标释放:mouseRelaseEvent鼠标移动:mouseMoveEvent 提升为自定义控件MyLabel 代码: //mylabel.h #ifndef MYLABEL_H #define MYLABEL_H#…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
flow_controllers
关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...
字符串哈希+KMP
P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...
基于 HTTP 的单向流式通信协议SSE详解
SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...
Cursor AI 账号纯净度维护与高效注册指南
Cursor AI 账号纯净度维护与高效注册指南:解决限制问题的实战方案 风车无限免费邮箱系统网页端使用说明|快速获取邮箱|cursor|windsurf|augment 问题背景 在成功解决 Cursor 环境配置问题后,许多开发者仍面临账号纯净度不足导致的限制问题。无论使用 16…...
