【算法与数据结构】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#…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
