代码随想录二刷 | 二叉树 | 合并二叉树

代码随想录二刷 | 二叉树 | 合并二叉树

题目描述

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

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

示例 1:
在这里插入图片描述
注意: 合并必须从两个树的根节点开始。

解题思路

递归

前中后序遍历都可以。这里以前序遍历为例。

  1. 确定递归函数的参数和返回值
    参数至少是传入两个二叉树的根节点,返回值就是合并后二叉树的根节点

    TreeNode* mergeTree(TreeNode* t1, TreeNode* t2)
    
  2. 确定递归的终止条件
    如果t1 == NULL,两个树合并后的根节点就应该是t2,如果此时t2也为NULL,那么合并后就是NULL。

    同理,如果t2 == NULL,两个树合并后的根节点就应该是t1。

    if (t1 == NULL) return t2;
    if (t2 == NULL) return 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;
		if (t2 == NULL) return 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;
		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->val != NULL && node2->val != NULL) {
				que.push(node1->left);
				que.push(ndoe2->left)
			}
			// 如果两个树右节点都不为空,加入队列
			if (node1->val != NULL && ndoe2->val != NULL) {
				que.push(node1->right);
				que.push(node2->right);
			}
			// 当t1的左节点为空,t2的左节点不为空,赋值过去
			if (node1->left == NULL && node2->left != NULL) {
				node2->left = node2->left;
			}
			// 当t1的右节点为空,t2的右节点不为空,赋值过去
			if (ndoe1->right == NULL && node2->right != NULL) {
				node2->right = node2->right;
			}
		}
		return t1;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值