当前位置: 首页 > news >正文

代码随想录阅读笔记-二叉树【合并二叉树】

题目

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

617.合并二叉树

注意: 合并必须从两个树的根节点开始。

思路 

相信这道题目很多人疑惑的点是如何同时遍历两个二叉树呢?

其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。

同样是递归和迭代两种思路

递归

二叉树使用递归,就要想使用前中后哪种遍历方式?

本题使用哪种遍历都是可以的!

我们下面以前序遍历为例。

动画如下:

617.合并二叉树

那么我们来按照递归三部曲来解决:

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

首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {

2、确定终止条件:

因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1

3、确定单层递归的逻辑:

单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。

那么单层递归中,就要把两棵树的元素加到一起。

t1->val += t2->val;

接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。

t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。

最终t1就是合并之后的根节点。

代码如下:

t1->left = mergeTrees(t1->left, t2->left);
t1->right = mergeTrees(t1->right, t2->right);
return t1;

此时前序遍历,完整代码就写出来了,如下:

class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1// 修改了t1的数值和结构t1->val += t2->val;                             // 中t1->left = mergeTrees(t1->left, t2->left);      // 左t1->right = mergeTrees(t1->right, t2->right);   // 右return t1;}
};

那么中序遍历也是可以的,代码如下:

class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1// 修改了t1的数值和结构t1->left = mergeTrees(t1->left, t2->left);      // 左t1->val += t2->val;                             // 中t1->right = mergeTrees(t1->right, t2->right);   // 右return t1;}
};

后序遍历依然可以,代码如下:

class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1// 修改了t1的数值和结构t1->left = mergeTrees(t1->left, t2->left);      // 左t1->right = mergeTrees(t1->right, t2->right);   // 右t1->val += t2->val;                             // 中return t1;}
};

但是前序遍历是最好理解的,我建议大家用前序遍历来做就OK。

如上的方法修改了t1的结构,当然也可以不修改t1和t2的结构,重新定义一个树。

不修改输入树的结构,前序遍历,代码如下:

class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2;if (t2 == NULL) return t1;// 重新定义新的节点,不修改原有两个树的结构TreeNode* root = new TreeNode(0);root->val = t1->val + t2->val;root->left = mergeTrees(t1->left, t2->left);root->right = mergeTrees(t1->right, t2->right);return root;}
};
迭代法

使用迭代法,如何同时处理两棵树呢?

思路我们在对称二叉树中的迭代法已经讲过一次了,求二叉树对称的时候就是把两个树的节点同时加入队列进行比较。

本题我们也使用队列,模拟的层序遍历,代码如下:

class Solution {
public:TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {if (t1 == NULL) return t2;if (t2 == NULL) return t1;queue<TreeNode*> que;que.push(t1);que.push(t2);while(!que.empty()) {TreeNode* node1 = que.front(); que.pop();TreeNode* node2 = que.front(); que.pop();// 此时两个节点一定不为空,val相加node1->val += node2->val;// 如果两棵树左节点都不为空,加入队列if (node1->left != NULL && node2->left != NULL) {que.push(node1->left);que.push(node2->left);}// 如果两棵树右节点都不为空,加入队列if (node1->right != NULL && node2->right != NULL) {que.push(node1->right);que.push(node2->right);}// 当t1的左节点 为空 t2左节点不为空,就赋值过去if (node1->left == NULL && node2->left != NULL) {node1->left = node2->left;}// 当t1的右节点 为空 t2右节点不为空,就赋值过去if (node1->right == NULL && node2->right != NULL) {node1->right = node2->right;}}return t1;}
};

原文中作者还拓展了一种单纯用指针的方式,大家可以参考学习。

如下代码中,想要更改二叉树的值,应该传入指向指针的指针。

代码如下:(前序遍历)

class Solution {
public:void process(TreeNode** t1, TreeNode** t2) {if ((*t1) == NULL && (*t2) == NULL) return;if ((*t1) != NULL && (*t2) != NULL) {(*t1)->val += (*t2)->val;}if ((*t1) == NULL && (*t2) != NULL) {*t1 = *t2;return;}if ((*t1) != NULL && (*t2) == NULL) {return;}process(&((*t1)->left), &((*t2)->left));process(&((*t1)->right), &((*t2)->right));}TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {process(&t1, &t2);return t1;}
};

相关文章:

代码随想录阅读笔记-二叉树【合并二叉树】

题目 给定两个二叉树&#xff0c;想象当你将它们中的一个覆盖到另一个上时&#xff0c;两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠&#xff0c;那么将他们的值相加作为节点合并后的新值&#xff0c;否则不为 NULL 的节…...

Day35:学习尚上优选项目

学习计划&#xff1a;完成尚硅谷的尚上优选项目 学习进度&#xff1a;尚上优选项目 知识点&#xff1a; 四、 搭建平台管理端前端环境 权限管理模块-用户管理 开发为用户分配角色接口用户管理前端测试 权限管理模块-菜单管理 菜单管理需求菜单表设计开发菜单管理CRUD接口开…...

c模板编程c/c++20240401

c模板编程 #include<iostream> //#include<string> //#include<algorithm> template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { int i max(1, 2); // 返回 2 float f max(3.14f, 2.72f); // 返回 3…...

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG,选择xwr68xx还是xwr64xx,及需要注意的问题

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG&#xff0c;选择xwr68xx还是xwr64xx&#xff0c;及需要注意的问题 文章目录 demo工程out_of_box文件调试bin文件名称需要注意的问题附录&#xff1a;结构框架雷达基本原理叙述雷达天线排列位置芯片框架Demo工程功能CCS工程导…...

连接Redis不支持集群错误,ERR This instance has cluster support disabled,解决方案

1. 问题背景 调整redis的配置后&#xff0c;启动程序时&#xff0c; 会报如下错误&#xff1a; [redis://172.16.0.8xxx]: ERR This instance has cluster support disabledSuppressed: io.lettuce.core.RedisCommandExecutionException: ERR This instance has cluster supp…...

什么是json?json可以存放哪几种数据类型

JSON指的是JavaScript对象表示法(avaScript Object Notation)&#xff0c;是轻量级的文本数据交换格式&#xff0c;独立于语言: JSON使用JavaScript语法来描述数据对象&#xff0c;但是JSON仍然独立于语言和平台&#xff0c;JSON解析器和JSON库支持许多不同的编程语言&#xff…...

网络编程套接字应用分享【Linux C/C++ 】【UDP应用 | TCP应用 | TCP线程池小项目】

目录 前提知识 1. 理解源ip&#xff0c;目的ip和Macip 2. 端口号 3. 初识TCP&#xff0c;UDP协议 4. 网络字节序 5. socket 编程 sockaddr类型 一&#xff0c;基于udp协议编程 1. socket——创建套接字 2. bind——将套接字强绑定 3. recvfrom——接受数据 4. s…...

有关数据开发项目中使用HIVE由于无法update和delete的场景下,如何解决数据增量的思路

解决数据增量问题的思路在Hive中 在数据开发项目中&#xff0c;使用Hive进行数据处理时&#xff0c;由于Hive不支持update和delete语句&#xff0c;处理数据增量可能会变得有些棘手。然而&#xff0c;有几种策略和技术可以帮助我们解决这个问题&#xff0c;并确保数据增量的高…...

两数之和-考察哈希表的运用

题目 给定一个整数数组 n u m s nums nums和一个整数目标值 t a r g e t target target&#xff0c;请你在该数组中找出和为目标值 t a r g e t target target的那 两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同…...

视觉检测系统,外观细节无可挑剔

在传统行业中&#xff0c;利用人工检测来检测产品外观缺陷依然是主流&#xff0c;但由于竞争的加剧&#xff0c;对企业生产效率的要求也越来越高。传统的检测产品外观缺陷问题的方法就是透过人工目检&#xff0c;或者工人采用游标卡尺等工具检测&#xff0c;此种方式检测速度慢…...

C++中string容器的字符串操作

目录 1.c_str() 返回C常量字符串 2.date() 返回C常量字符串 3.substr() 构造子串 4.find() 正向查找&#xff08;查找失败返回npos&#xff09; 5.rfind() 逆向查找&#xff08;查找失败返回npos&#xff09; 6.find_first_of() 正向查找匹配的字符 7.find_last_of() 逆向…...

Java编程使用CGLIB动态代理介绍与实战演示

文章目录 前言技术积累核心概念主要功能适用场景与JDK动态代理的对比 实战演示定义待代理的目标类实现MethodInterceptor接口使用代理对象 测试结果写在最后 前言 在Java编程中&#xff0c;CGLIB (Code Generation Library) 是一个强大的高性能代码生成库&#xff0c;它通过生…...

vue3 渲染一个后端返回的图片字段渲染、table表格内放置图片

一、后端直接返回图片url 当图片字段接口直接返回的是图片url&#xff0c;可以直接放到img标签上 <img v-if"thumbLoader" class"r-image-loader-thumb" :src"resUrl" /> 二、当图片字段接口直接返回的是图片Id 那么就需要去拼一下图片…...

iOS开发进阶(十三):脚手架创建iOS项目

文章目录 一、前言二、xcode-select 命令三、拓展阅读 一、前言 项目初期&#xff0c;需要搭建项目基本框架&#xff0c;为此离不开辅助工具&#xff0c;即脚手架。当然&#xff0c;IDE也可以实现新建空白项目&#xff0c;但是其新建后的项目结构可能不符合预期设计&#xff0…...

手机无线投屏到windows11电脑

1 安装无线投影组件 2 电脑端打开允许其他设备投影的开关 3 手机找到投屏选项 4 手机搜索可用设备连接即可 这里的官方文档给的不太好,给了一些让人眼花撩乱的信息,以下是经过整合的有效信息...

linux 环境安装配置

安装java17 1.下载安装包 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz 2.解压到自定义目录/usr/local/java mkdir /usr/local/java tar zxvf jdk-17_linux-x64_bin.tar.gz -C /usr/local/java 3.配置环境变量 echo export PATH$PATH:/…...

Git常用语句

设置用户名 git config --global user.name "用户名" git config --global user.email "邮箱"查看git用户信息 cat ~/.gitconfig初始化本地库 git initclone指定分支的代码 git clone -b my_branch gitgitlabxxxxxxxxxxxxxxxxxxxxxx.gitpush三件套 gi…...

坦克大战_java源码_swing界面_带毕业论文

一. 演示视频 坦克大战_java源码_swing界面_带毕业论文 二. 实现步骤 完整项目获取 https://githubs.xyz/y22.html 部分截图 启动类是 TankClinet.java&#xff0c;内置碰撞检测算法&#xff0c;线程&#xff0c;安全集合&#xff0c;一切皆对象思想等&#xff0c;是java进阶…...

JVM 记录

记录 工具 https://gceasy.io 资料 尚硅谷宋红康JVM全套教程&#xff08;详解java虚拟机&#xff09; https://www.bilibili.com/video/BV1PJ411n7xZ?p361 全套课程分为《内存与垃圾回收篇》《字节码与类的加载篇》《性能监控与调优篇》三个篇章。 上篇《内存与垃圾回收篇…...

Linux学习笔记————C 语言版 LED 灯实验

这里写目录标题 一、实验程序编写二、 汇编部分实验程序编写三、C 语言部分实验程序编写四、编译下载验证 汇编 LED 灯实验中&#xff0c;我们讲解了如何使用汇编来编写 LED 灯驱动&#xff0c;实际工作中是很少用到汇编去写嵌入式驱动的&#xff0c;毕竟汇编太难&#xff0c;而…...

MCMC可视化指南:用动画理解马尔可夫链的收敛过程

MCMC可视化指南&#xff1a;用动画理解马尔可夫链的收敛过程 在数据科学和统计建模领域&#xff0c;马尔可夫链蒙特卡洛(MCMC)方法已经成为解决复杂概率分布采样问题的利器。但对于初学者而言&#xff0c;理解马尔可夫链如何通过随机游走最终收敛到目标分布&#xff0c;往往是…...

终极指南:如何用Zotero PDF Translate插件快速突破学术语言壁垒

终极指南&#xff1a;如何用Zotero PDF Translate插件快速突破学术语言壁垒 【免费下载链接】zotero-pdf-translate 支持将PDF、EPub、网页内容、元数据、注释和笔记翻译为目标语言&#xff0c;并且兼容20多种翻译服务。 项目地址: https://gitcode.com/gh_mirrors/zo/zotero…...

智能物流分拣破局:越疆协作分拣机器人高效升级指南

在电商、快递行业的高速发展下&#xff0c;物流分拣的压力越来越大&#xff0c;但长期以来&#xff0c;中小物流企业的分拣面临 “两难” 困境&#xff1a;人工分拣招工难、效率低&#xff0c;错分率达 1% 以上&#xff0c;大促期间更是人手不足&#xff1b;而传统的交叉带分拣…...

SDMatte在老旧照片修复流程中的关键作用:人物与背景分离

SDMatte在老旧照片修复流程中的关键作用&#xff1a;人物与背景分离 1. 老照片修复的挑战与解决方案 老照片承载着珍贵的记忆&#xff0c;但时间往往会在这些影像上留下痕迹——褪色、划痕、污渍甚至物理破损。传统修复方法需要专业设计师耗费大量时间手动处理&#xff0c;而…...

从零开始:在VMware虚拟机中部署Janus-Pro-7B进行开发测试

从零开始&#xff1a;在VMware虚拟机中部署Janus-Pro-7B进行开发测试 想试试最新的AI大模型&#xff0c;但手头没有昂贵的独立GPU服务器&#xff1f;别担心&#xff0c;今天我们就来聊聊一个非常接地气的方案&#xff1a;用你手边的普通电脑&#xff0c;通过VMware虚拟机&…...

AI赋能Spring开发:借助快马平台快速集成Spring AI,打造智能应用

AI赋能Spring开发&#xff1a;借助快马平台快速集成Spring AI&#xff0c;打造智能应用 Spring生态庞大&#xff0c;新技术集成往往需要查阅大量文档。最近我在尝试将Spring AI集成到项目中&#xff0c;发现这个过程比想象中要复杂得多。好在发现了InsCode(快马)平台&#xff…...

破解B站评论区识人困境!B站成分检测器让用户画像识别效率飙升8倍

破解B站评论区识人困境&#xff01;B站成分检测器让用户画像识别效率飙升8倍 【免费下载链接】bilibili-comment-checker B站评论区自动标注成分&#xff0c;支持动态和关注识别以及手动输入 UID 识别 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-comment-checke…...

网易云音乐评论数据分析:用Python爬取+可视化热门歌曲情感倾向

网易云音乐评论数据挖掘&#xff1a;从爬取到情感分析的完整实战指南 音乐平台的用户评论蕴含着丰富的情感价值和商业洞察。作为国内领先的音乐社区&#xff0c;网易云音乐的海量评论数据对产品经理优化功能、市场人员分析用户偏好具有重要价值。本文将系统性地介绍如何通过Pyt…...

CHORD-X从零开始:C语言基础概念学习报告自动生成教程

CHORD-X从零开始&#xff1a;C语言基础概念学习报告自动生成教程 你是不是也遇到过这样的烦恼&#xff1f;作为编程老师&#xff0c;每次讲完C语言的指针、结构体这些难点&#xff0c;总想给学生一份清晰易懂的复习报告&#xff0c;但自己动手整理又太花时间。或者&#xff0c…...

【Matlab】MATLAB教程:数据插值interp1(案例:interp1(x,y,xi,‘linear‘);应用:数据补全、插值)

MATLAB教程:数据插值interp1(案例:interp1(x,y,xi,linear);应用:数据补全、插值) 在科研实验、工程监测、信号采集等各类数据获取场景中,受限于设备精度、测试条件、环境干扰等因素,采集到的原始数据往往存在**数据点稀疏、采样间隔不均、局部数据缺失**等问题,直接使…...