二叉树21:合并二叉树

news2025/1/20 22:02:41

主要是我自己刷题的一些记录过程。如果有错可以指出哦,大家一起进步。
转载代码随想录
原文链接:
代码随想录
leetcode链接:617. 合并二叉树

题目:

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点

返回合并后的二叉树。

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

示例:

示例 1:
在这里插入图片描述

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

两棵树中的节点数目在范围 [0, 2000] 内
-104 <= Node.val <= 104

思路:

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

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

递归

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

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

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

动画如下:

请添加图片描述
那么我们来按照递归三部曲来解决:

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为空,合并之后就应该是t2
        if (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为空,合并之后就应该是t2
        if (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为空,合并之后就应该是t2
        if (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:
	TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
		TreeNode* root;
		if (!root1&& !root2) {
			return nullptr;
		}
		else if (!root1) {
			root = root2;
			return root;
		}
		else if (!root2) {
			root = root1;
			return root;
		}
		else  {
			root = new TreeNode(root1->val + root2->val);
		}

		root->left = mergeTrees(root1->left, root2->left);
		root->right = mergeTrees(root1->right, root2->right);
		return root;
	}
};

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

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

相关文章

Vuex状态管理

Vuex&#xff1a;管理组件中共用的一些状态&#xff0c;并能够做一些操作 一、准备工作 安装Vuex ① 默认安装vuex4版本&#xff1a;执行命令 npm install vuex ② 指定安装vuex3版本&#xff1a;执行命令 npm install vuex3 引入Vuex 在src目录下新建名称为store的文件夹&am…

微信小程序wxss相关介绍、全局配置和tabbar知识以及发送数据请求(post,get)

wxss相关介绍 什么是wxss??? wxss (WeiXin Style Sheets)是一套样式语言&#xff0c;用于美化WXML的组件样式&#xff0c;类似于网页开发中的CSS。 WXSS 具有CSS大部分特性&#xff0c;同时&#xff0c;WXSS还对CSS进行了扩充以及修改&#xff0c;以适应微信小程序的开发。 …

数据探索性分析(EDA)——不平衡样本处理

1、何为不平衡样本&#xff1f; 样本不平衡是指分类任务中不同类别的训练样例数目差别很大的情况。在实际的分类任务中&#xff0c;我们经常会遇到类别不平衡&#xff0c;例如广告点击率预测、情感分类、异常检测等。而机器学习算法通常假设不同类别的样本数量大致相似&#x…

【4】k8s_NameSpacePod

目录 一、NameSpace 二、Pod 【1】命令式对象管理: 直接使用命令去操作kubernetes资源 【2】命令式对象配置: 通过命令配置和配置文件去操作作kubernetes资源 1、写一个ymal文件 2、然后运行yaml文件&#xff08;提前创建好了命名空间string&#xff09; 3、用bashboard创…

案例分享|方形锂电池铝壳外观缺陷检测

SNE Research最新披露的数据显示&#xff0c;2022年1-11月&#xff0c;宁德时代、比亚迪和中航锂电三家中国企业合计占全球动力电池市场份额的54.7%&#xff0c;排名前十的动力电池企业中&#xff0c;中国企业占据6席&#xff0c;合计市场份额达到64.5%。随着动力电池企业的强势…

数据库管理-第五十二期 有感~而发(20230113)

数据库管理 2023-01-13第五十二期 有感~而发1 AHF2 系统3 文档总结第五十二期 有感~而发 再过一周就过年了&#xff0c;感觉时间过得好快&#xff0c;但是又好忙&#xff0c;总在协助处理紧急时间和异常&#xff0c;忙的停不下来。 1 AHF 最近对X9M那台一体机&#xff0c;主…

力扣16.最接近的三数之和

力扣16.最接近的三数之和 题目描述 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,…

(1)python pyinstaller打包exe添加版本信息(2)python获取exe版本信息(3)pyqt5开发exe添加检查版本更新功能

笔者总结不容易点个关注吧 一键三联哦! 感谢您! python pyinstaller打包exe添加版本信息 打包并添加版本信息 注意!这里有个坑 如果第二次要修改版权信息 要将file_version_info.txt改为新的名称才生效 pyinstaller --version-file file_version_info.txt -D -w …

【bug】【vxe-table】设置固定列,表头后端返,样式错乱已解决

bug产生的原因以及解决的方法都很简单 但是要复现bug&#xff0c;就得把前因都铺垫清楚才行 一、前因 项目用的是vxe-table&#xff0c;并且封装成了组件&#xff0c;方便大量调用 并且column是后端动态返的&#xff0c;只需要绑定指定id给后端就行&#xff0c;大概就是这样&a…

npm ERR! Unexpected token ‘.‘ 报错解决办法

报错截图如下&#xff1a; 每次使用 nvm 将 node 切换到高版本后&#xff0c;运行 npm 相关的命令就报这个错&#xff0c;网上搜寻一番后&#xff0c;现将解决办法进行记录。 解决办法&#xff1a; 1、通过 nvm uninstall [version] 命令将已经安装的 node 版本依次删除。 [v…

CHAPTER 7 *使用Dockerfile创建镜像

dockerfile7.1 基本结构7.2 指令说明7.2.1 ARG7.2.2 FROM7.2.3 LABEL7.2.4 EXPOSE7.2.5 ENV7.2.6 ENTRYPOINT7.2.7 VOLUME7.2.8 USER7.2.9 WORKDIR7.2.10 ONBUILD7.2.11 STOPSIGNAL7.2.11 HEALTHCHECK7.2.12 SHELL7.2.13 RUN7.2.14 CMD7.2.15 ADD7.2.16 COPY7.3 创建镜像7.3.1 …

版本控制 | 设计师和美术人员的理想版本控制软件是?

版本控制对于开发人员来说是必不可少的工具。但今天&#xff0c;开发已经不仅仅包括代码。让美术人员和设计师使用版本控制能够集中协作&#xff0c;并保护宝贵的数字资产。 本篇文章将分析为什么版本控制对设计师也如此重要&#xff0c;并且回答一个重要的问题——对于设计师…

HTML实现闪电打字效果

演示 完整HTML <!doctype html> <html> <head> <meta charset"utf-8"> <title>H5 Canvas雷电打出文字特效</title><style> .page-thunder-to-text {position: relative;overflow: hidden; } .page-thunder-to-text canv…

每日坚果“鼻祖”,沃隆再闯IPO

成于坚果&#xff0c;困于坚果&#xff1f;“坚果大队长”沃隆再次闯关IPO。“每日坚果鼻祖”青岛沃隆食品股份有限公司&#xff08;下称“沃隆”&#xff09;于1月6日更新招股书&#xff0c;拟登陆上交所主板。沃隆是一家以坚果相关产品为核心的休闲食品生产商&#xff0c;主要…

SAP PP 生产版本主数据维护

PP生产版本主数据 生产版本&#xff08;Production Version&#xff09;主数据是执行生产业务过程中最主要的基础数据之一&#xff0c;包含了产品的数量结构信息&#xff0c;同时也包含了产品的工艺路线&#xff0c;工作中心等信息。生产版本主记录里包含了产品代码、工艺路线、…

三,Spring AOP

Spring AOP 1 代理设计模式 1.1 解决的问题 Service层中除了核心代码&#xff08;调用dao逻辑判断&#xff09;外&#xff0c;还有事务控制这种额外的增强功能。现在我们将核心业务代码和事务控制增强编码在一起直接定义在service层&#xff0c;日后还可能会新增其它的额外功…

docker安装与基本介绍使用

Docker 一、初识Docker 1、安装Docker # 1.yum包更新到最新 yum update # 2.安装需要的软件包&#xff0c;yum-util提供的yum-config-manager&#xff0c;例外两个是devicemapper驱动依赖的 yum install -y yum-utils device-mapper-persistent-data lvm2 # 3.设置yum源 yum…

hololens2开发环境配置,游戏引擎的全流程安装部署

要进行hololens 2的项目开发&#xff0c;进行基础环境搭建和软件安装部署的记录。 软件安装 UE ue2.6x(安装hololens平台)openxr插件&#xff0c;ux插件&#xff08;可选&#xff09; unity3d unity3d 2020&#xff08;unity3d 2021在打包时&#xff0c;在universal windo…

预测2023:智算中心将人工智能产业推上发展的“拐点”?

文|智能相对论作者|沈浪回顾过去的2022年&#xff0c;人工智能产业继续在巨变中迎来突破性成长。一方面&#xff0c;人工智能产业相关的应用越来越丰富、创新&#xff0c;比如元宇宙的出现和走红&#xff0c;为市场创造的一个全新的业态&#xff0c;也为用户带来了诸多新奇的体…

RabbitMQ 部署及配置详解

一、RabbitMQ 核心概念1. 生产者和消费者Producer: 消息的生产者,用于发布消息&#xff1b;Consumer: 消息的消费者&#xff0c;用于从队列中获取消息.消费者只需关注队列即可&#xff0c;不需要关注交换机和路由键。消费者可以通过basicConsume(订阅模式可以从队列中一直持续的…