代码随想录阅读笔记-二叉树【翻转二叉树】

题目

翻转一棵二叉树。

226.翻转二叉树

思路

如果要从整个树来看,翻转还真的挺复杂,整个树以中间分割线进行翻转,如图:

226.翻转二叉树1

可以发现想要翻转它,其实就把每一个节点的左右孩子交换一下就可以了。

关键在于遍历顺序,前中后序应该选哪一种遍历顺序? 

遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。

注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!建议拿纸画一画,就理解了

那么层序遍历可以不可以呢?依然可以的!只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!

下面便和之前的遍历一样,从递归和迭代两种角度出发解题

递归法

我们下文以前序遍历为例,通过动画来看一下翻转的过程:

翻转二叉树

我们来看一下递归三部曲:

1、确定递归函数的参数和返回值

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

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

TreeNode* invertTree(TreeNode* root)

2、确定终止条件

当前节点为空的时候,就返回

if (root == NULL) return root;

3、确定单层递归的逻辑

因为是前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

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

基于这递归三步法,C++代码如下:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 左
        invertTree(root->right);        // 右
        return root;
    }
};

迭代法

深度优先遍历

之前的博客中给出了前中后序迭代方式的写法,所以本题可以很轻松的写出如下迭代法的代码:

C++代码迭代法(前序遍历)

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        stack<TreeNode*> st;
        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;
    }
};

如果这个代码看不懂的话可以再回顾一下代码随想录阅读笔记-二叉树【迭代遍历】-CSDN博客

我们在代码随想录阅读笔记-二叉树【统一迭代法】-CSDN博客中介绍了统一的写法,所以,本题也只需将文中的代码少做修改便可。

C++代码如下统一迭代法(前序遍历)

class Solution {
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 Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                swap(node->left, node->right); // 节点处理
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return root;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何通过vscode连接到wsl

下载wsl扩展 远程连接模式

SQL Server 实验二:数据库视图的创建和使用

目录 第一关 相关知识 什么是表 操作数据表 创建数据表 插入数据 修改表结构 删除数据表 编程要求 第一关实验代码&#xff1a; 第二关 相关知识 视图是什么 视图的优缺点 视图的优点 视图的缺点 操作视图 创建视图 通过视图向基本表中插入数据 通过视图修改基本表的…

Selenium元素定位之页面检测技巧

在进行web自动化测试的时候进行XPath或者CSS定位&#xff0c;需要检测页面元素定位是否正确&#xff0c;如果用脚本去检测&#xff0c;那么效率是极低的。 一般网上推选装额外的插件来实现页面元素定位检测 如&#xff1a;firebug。 其实F12开发者工具就能直接在页面上检测元…

JavaScript new一个对象的详细过程

JavaScript new一个对象的详细过程 new实现过程 new实现原理 new手写实现 实现过程/原理 开辟一块内存&#xff0c;创建一个空对象 执行构造函数对这个空对象进行构造 给空对象添加__proto__属性 调用函数改变this指向 最后返回this指向的新对象&#xff08;如果是引用类型则返…

C# OpenCvSharp MatchTemplate 多目标匹配

目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp; using O…

Collection集合 --java学习笔记

Collection Collection是单列集合的祖宗&#xff0c;它规定的方法&#xff08;功能&#xff09;是全部单列集合都会继承的 List系列集合&#xff1a;List系列集合&#xff1a;ArrayList、LinkedList --java学习笔记-CSDN博客 Set系列集合&#xff1a;Set系列集合&#xff1a;…

ARMv9新特性:虚拟内存系统架构 (VMSA) 的增强功能

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 权限索引 2022 ARM引入了一种新的控制内存权限方法。 不再是直接在转换表条目 (TTE) 中编码权限&#xff0c;而是使用 TTE 中的字段来索引寄存器中指定的权限数组。这种间接提供…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言&#xff1a; 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…

蓝桥杯单片机---第十一届省赛题目解析

文章目录 比赛题目一、代码相关定义、声明1.头文件声明2.变量声明 二、主要函数1.main函数2.按键扫描3.数码管显示4.电压 & LED显示5.定时器中断6.消除85C显示 三、次要函数1.初始化函数Init2.按键函数Key3.LED函数Led4.数码管函数Seg5.iic函数中6.onewire函数中 总结 比赛…

【Redis】redis主从复制

概述 常见的Redis高可用的方案包括持久化、主从复制&#xff08;及读写分离&#xff09;、哨兵和集群。其中持久化侧重解决的是Redis数据的单机备份问题&#xff08;从内存到硬盘的备份&#xff09;&#xff1b;而主从复制则侧重解决数据的多机热备。此外&#xff0c;主从复制…

鸿蒙TypeScript入门学习第4天:【TS变量声明】

1、TypeScript 变量声明 变量是一种使用方便的占位符&#xff0c;用于引用计算机内存地址。 我们可以把变量看做存储数据的容器。 TypeScript 变量的命名规则&#xff1a; 变量名称可以包含数字和字母。除了下划线 _ 和美元 $ 符号外&#xff0c;不能包含其他特殊字符&…

使用ai智能写作场景之gpt整理资料,如何ai智能写作整理资料

Ai智能写作助手&#xff1a;Ai智能整理资料小助手 Ai智能整理资料小助手可试用3天&#xff01; 通俗的解释一下怎么用ChatGPT来进行资料整理&#xff1a; 搜寻并获取指定数量的特定领域文章&#xff1a; 想像你在和我说话一样&#xff0c;告诉我你想要多少篇关于某个话题的文…

高效实用的Java输出流:BufferWriter类详解

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,…

ardupilot开发 --- Remote ID 篇

朝花夕拾 什么是 Remote ID &#xff1f;一些概念OpenDroneIDArduRemoteIDopendroneid-core-c 库 什么是 Remote ID &#xff1f; https://drone-remote-id.com/ 一些概念 符合美国航空管理局FAA规定的一些 Remote ID 设备有哪些&#xff1f; https://uasdoc.faa.gov/listDoc…

【APP_TYC】数据采集案例天眼APP查_查壳脱壳反编译_③

是不是生活太艰难 还是活色生香 我们都遍体鳞伤 也慢慢坏了心肠 你得到你想要的吗 换来的是铁石心肠 可曾还有什么人 再让你幻想 &#x1f3b5; 朴树《清白之年》 查壳 工具介绍Frida-dexDump Frida-dexDump简介 Frida-dexDump是基于Frida的一个工具&…

Java中读取html文件转成String,展示在浏览器

这里写目录标题 第一章1.1&#xff09;pom中引入依赖和html文件示例1.2&#xff09;使用hutool工具包读取html文件转为string1.3&#xff09;页面显示 第一章 1.1&#xff09;pom中引入依赖和html文件示例 引入hutool工具包依赖 <dependency><groupId>cn.hutool&…

vue前端工程化

前言 本文介绍的是有关于vue方面的前端工程化实践&#xff0c;主要通过实践操作让开发人员更好的理解整个前端工程化的流程。 本文通过开发准备阶段、开发阶段和开发完成三个阶段开介绍vue前端工程化的整体过程。 准备阶段 准备阶段我将其分为&#xff1a;框架选择、规范制…

html安装及入门

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、简单介绍一下前端三大件开发工具 二、安装VSCode三、VSCode相关配置1.汉化2.live server3.使用前 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下…

治愈自己的短句,心灵鸡汤!

一、不是所有的是非都能理清&#xff0c;不是所有的付出都有收获。有些选择是无可奈何&#xff0c;有些失去是注定的。与其无法言说&#xff0c;不如一笑而过&#xff1b;与其无法释怀&#xff0c;不如安然自若。 二、没人会真正的感同身受到你的痛楚&#xff0c;也没人会真正…

如何通过使用yolov8实现火灾烟雾检测

在该项目中&#xff0c;对原始YOLO模型进行训练集数据收集、模型结构调整、超参数优化等步骤&#xff0c;使其能够准确高效地从视频或图像中识别出火源或其他火灾相关特征&#xff0c;以实现实时火警监测、预警等功能。 介绍 该代码库包含使用YOLOv8在实时视频中跟踪和检测火灾…