代码随想录二刷 | 二叉树 | 合并二叉树
- 题目描述
- 解题思路
- 递归
- 迭代
- 代码实现
- 递归
- 迭代
题目描述
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
注意: 合并必须从两个树的根节点开始。
解题思路
递归
前中后序遍历都可以。这里以前序遍历为例。
-
确定递归函数的参数和返回值
参数至少是传入两个二叉树的根节点,返回值就是合并后二叉树的根节点TreeNode* mergeTree(TreeNode* t1, TreeNode* t2)
-
确定递归的终止条件
如果t1 == NULL
,两个树合并后的根节点就应该是t2,如果此时t2也为NULL,那么合并后就是NULL。同理,如果
t2 == NULL
,两个树合并后的根节点就应该是t1。if (t1 == NULL) return t2; if (t2 == NULL) return t1;
-
确定单层递归的逻辑
我们重复利用一下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;}
};