797 lines
24 KiB
Markdown
797 lines
24 KiB
Markdown
<p align="center">
|
||
<a href="https://programmercarl.com/other/xunlianying.html" target="_blank">
|
||
<img src="../pics/训练营.png" width="1000"/>
|
||
</a>
|
||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||
|
||
|
||
# 617.合并二叉树
|
||
|
||
[力扣题目链接](https://leetcode.cn/problems/merge-two-binary-trees/)
|
||
|
||
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
|
||
|
||
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
|
||
|
||
示例 1:
|
||
|
||

|
||
|
||
注意: 合并必须从两个树的根节点开始。
|
||
|
||
## 算法公开课
|
||
|
||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树](https://www.bilibili.com/video/BV1m14y1Y7JK),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||
|
||
|
||
## 思路
|
||
|
||
相信这道题目很多同学疑惑的点是如何同时遍历两个二叉树呢?
|
||
|
||
其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。
|
||
|
||
### 递归
|
||
|
||
二叉树使用递归,就要想使用前中后哪种遍历方式?
|
||
|
||
**本题使用哪种遍历都是可以的!**
|
||
|
||
我们下面以前序遍历为例。
|
||
|
||
动画如下:
|
||
|
||

|
||
|
||
那么我们来按照递归三部曲来解决:
|
||
|
||
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;
|
||
```
|
||
|
||
此时前序遍历,完整代码就写出来了,如下:
|
||
|
||
```CPP
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
那么中序遍历也是可以的,代码如下:
|
||
|
||
```CPP
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
后序遍历依然可以,代码如下:
|
||
|
||
```CPP
|
||
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的结构,重新定义一个树。
|
||
|
||
不修改输入树的结构,前序遍历,代码如下:
|
||
|
||
```CPP
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
### 迭代法
|
||
|
||
使用迭代法,如何同时处理两棵树呢?
|
||
|
||
思路我们在[二叉树:我对称么?](https://programmercarl.com/0101.对称二叉树.html)中的迭代法已经讲过一次了,求二叉树对称的时候就是把两个树的节点同时加入队列进行比较。
|
||
|
||
本题我们也使用队列,模拟的层序遍历,代码如下:
|
||
|
||
```CPP
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
## 拓展
|
||
|
||
当然也可以秀一波指针的操作,这是我写的野路子,大家就随便看看就行了,以防带跑偏了。
|
||
|
||
如下代码中,想要更改二叉树的值,应该传入指向指针的指针。
|
||
|
||
代码如下:(前序遍历)
|
||
```CPP
|
||
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;
|
||
}
|
||
};
|
||
```
|
||
|
||
## 总结
|
||
|
||
合并二叉树,也是二叉树操作的经典题目,如果没有接触过的话,其实并不简单,因为我们习惯了操作一个二叉树,一起操作两个二叉树,还会有点懵懵的。
|
||
|
||
这不是我们第一次操作两棵二叉树了,在[二叉树:我对称么?](https://programmercarl.com/0101.对称二叉树.html)中也一起操作了两棵二叉树。
|
||
|
||
迭代法中,一般一起操作两个树都是使用队列模拟类似层序遍历,同时处理两个树的节点,这种方式最好理解,如果用模拟递归的思路的话,要复杂一些。
|
||
|
||
最后拓展中,我给了一个操作指针的野路子,大家随便看看就行了,如果学习C++的话,可以再去研究研究。
|
||
|
||
|
||
## 其他语言版本
|
||
|
||
|
||
### Java
|
||
|
||
```Java
|
||
class Solution {
|
||
// 递归
|
||
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
|
||
if (root1 == null) return root2;
|
||
if (root2 == null) return root1;
|
||
|
||
root1.val += root2.val;
|
||
root1.left = mergeTrees(root1.left,root2.left);
|
||
root1.right = mergeTrees(root1.right,root2.right);
|
||
return root1;
|
||
}
|
||
}
|
||
```
|
||
|
||
```Java
|
||
class Solution {
|
||
// 使用栈迭代
|
||
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
|
||
if (root1 == null) {
|
||
return root2;
|
||
}
|
||
if (root2 == null) {
|
||
return root1;
|
||
}
|
||
Stack<TreeNode> stack = new Stack<>();
|
||
stack.push(root2);
|
||
stack.push(root1);
|
||
while (!stack.isEmpty()) {
|
||
TreeNode node1 = stack.pop();
|
||
TreeNode node2 = stack.pop();
|
||
node1.val += node2.val;
|
||
if (node2.right != null && node1.right != null) {
|
||
stack.push(node2.right);
|
||
stack.push(node1.right);
|
||
} else {
|
||
if (node1.right == null) {
|
||
node1.right = node2.right;
|
||
}
|
||
}
|
||
if (node2.left != null && node1.left != null) {
|
||
stack.push(node2.left);
|
||
stack.push(node1.left);
|
||
} else {
|
||
if (node1.left == null) {
|
||
node1.left = node2.left;
|
||
}
|
||
}
|
||
}
|
||
return root1;
|
||
}
|
||
}
|
||
```
|
||
```java
|
||
class Solution {
|
||
// 使用队列迭代
|
||
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
|
||
if (root1 == null) return root2;
|
||
if (root2 ==null) return root1;
|
||
Queue<TreeNode> queue = new LinkedList<>();
|
||
queue.offer(root1);
|
||
queue.offer(root2);
|
||
while (!queue.isEmpty()) {
|
||
TreeNode node1 = queue.poll();
|
||
TreeNode node2 = queue.poll();
|
||
// 此时两个节点一定不为空,val相加
|
||
node1.val = node1.val + node2.val;
|
||
// 如果两棵树左节点都不为空,加入队列
|
||
if (node1.left != null && node2.left != null) {
|
||
queue.offer(node1.left);
|
||
queue.offer(node2.left);
|
||
}
|
||
// 如果两棵树右节点都不为空,加入队列
|
||
if (node1.right != null && node2.right != null) {
|
||
queue.offer(node1.right);
|
||
queue.offer(node2.right);
|
||
}
|
||
// 若node1的左节点为空,直接赋值
|
||
if (node1.left == null && node2.left != null) {
|
||
node1.left = node2.left;
|
||
}
|
||
// 若node1的右节点为空,直接赋值
|
||
if (node1.right == null && node2.right != null) {
|
||
node1.right = node2.right;
|
||
}
|
||
}
|
||
return root1;
|
||
}
|
||
}
|
||
```
|
||
|
||
### Python
|
||
(版本一) 递归 - 前序 - 修改root1
|
||
```python
|
||
# Definition for a binary tree node.
|
||
# class TreeNode:
|
||
# def __init__(self, val=0, left=None, right=None):
|
||
# self.val = val
|
||
# self.left = left
|
||
# self.right = right
|
||
class Solution:
|
||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||
# 递归终止条件:
|
||
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
|
||
if not root1:
|
||
return root2
|
||
if not root2:
|
||
return root1
|
||
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
|
||
root1.val += root2.val # 中
|
||
root1.left = self.mergeTrees(root1.left, root2.left) #左
|
||
root1.right = self.mergeTrees(root1.right, root2.right) # 右
|
||
|
||
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
|
||
|
||
```
|
||
(版本二) 递归 - 前序 - 新建root
|
||
```python
|
||
# Definition for a binary tree node.
|
||
# class TreeNode:
|
||
# def __init__(self, val=0, left=None, right=None):
|
||
# self.val = val
|
||
# self.left = left
|
||
# self.right = right
|
||
class Solution:
|
||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||
# 递归终止条件:
|
||
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
|
||
if not root1:
|
||
return root2
|
||
if not root2:
|
||
return root1
|
||
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
|
||
root = TreeNode() # 创建新节点
|
||
root.val += root1.val + root2.val# 中
|
||
root.left = self.mergeTrees(root1.left, root2.left) #左
|
||
root.right = self.mergeTrees(root1.right, root2.right) # 右
|
||
|
||
return root # ⚠️ 注意: 本题我们创建了新节点.
|
||
|
||
```
|
||
|
||
(版本三) 迭代
|
||
```python
|
||
class Solution:
|
||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||
if not root1:
|
||
return root2
|
||
if not root2:
|
||
return root1
|
||
|
||
queue = deque()
|
||
queue.append(root1)
|
||
queue.append(root2)
|
||
|
||
while queue:
|
||
node1 = queue.popleft()
|
||
node2 = queue.popleft()
|
||
# 更新queue
|
||
# 只有两个节点都有左节点时, 再往queue里面放.
|
||
if node1.left and node2.left:
|
||
queue.append(node1.left)
|
||
queue.append(node2.left)
|
||
# 只有两个节点都有右节点时, 再往queue里面放.
|
||
if node1.right and node2.right:
|
||
queue.append(node1.right)
|
||
queue.append(node2.right)
|
||
|
||
# 更新当前节点. 同时改变当前节点的左右孩子.
|
||
node1.val += node2.val
|
||
if not node1.left and node2.left:
|
||
node1.left = node2.left
|
||
if not node1.right and node2.right:
|
||
node1.right = node2.right
|
||
|
||
return root1
|
||
```
|
||
(版本四) 迭代 + 代码优化
|
||
```python
|
||
# Definition for a binary tree node.
|
||
# class TreeNode:
|
||
# def __init__(self, val=0, left=None, right=None):
|
||
# self.val = val
|
||
# self.left = left
|
||
# self.right = right
|
||
from collections import deque
|
||
|
||
class Solution:
|
||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||
if not root1:
|
||
return root2
|
||
if not root2:
|
||
return root1
|
||
|
||
queue = deque()
|
||
queue.append((root1, root2))
|
||
|
||
while queue:
|
||
node1, node2 = queue.popleft()
|
||
node1.val += node2.val
|
||
|
||
if node1.left and node2.left:
|
||
queue.append((node1.left, node2.left))
|
||
elif not node1.left:
|
||
node1.left = node2.left
|
||
|
||
if node1.right and node2.right:
|
||
queue.append((node1.right, node2.right))
|
||
elif not node1.right:
|
||
node1.right = node2.right
|
||
|
||
return root1
|
||
|
||
|
||
```
|
||
### Go
|
||
|
||
```go
|
||
// 前序遍历
|
||
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
|
||
if root1 == nil {
|
||
return root2
|
||
}
|
||
if root2 == nil {
|
||
return root1
|
||
}
|
||
root1.Val += root2.Val
|
||
root1.Left = mergeTrees(root1.Left, root2.Left)
|
||
root1.Right = mergeTrees(root1.Right, root2.Right)
|
||
return root1
|
||
}
|
||
|
||
// 迭代版本
|
||
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
|
||
queue := make([]*TreeNode,0)
|
||
if root1 == nil{
|
||
return root2
|
||
}
|
||
if root2 == nil{
|
||
return root1
|
||
}
|
||
queue = append(queue,root1)
|
||
queue = append(queue,root2)
|
||
|
||
for size := len(queue); size>0; size=len(queue) {
|
||
node1 := queue[0]
|
||
queue = queue[1:]
|
||
node2 := queue[0]
|
||
queue = queue[1:]
|
||
node1.Val += node2.Val
|
||
// 左子树都不为空
|
||
if node1.Left != nil && node2.Left != nil {
|
||
queue = append(queue,node1.Left)
|
||
queue = append(queue,node2.Left)
|
||
}
|
||
// 右子树都不为空
|
||
if node1.Right !=nil && node2.Right !=nil {
|
||
queue = append(queue, node1.Right)
|
||
queue = append(queue, node2.Right)
|
||
}
|
||
// 树 1 的左子树为 nil,直接接上树 2 的左子树
|
||
if node1.Left == nil {
|
||
node1.Left = node2.Left
|
||
}
|
||
// 树 1 的右子树为 nil,直接接上树 2 的右子树
|
||
if node1.Right == nil {
|
||
node1.Right = node2.Right
|
||
}
|
||
}
|
||
return root1
|
||
}
|
||
```
|
||
|
||
### JavaScript
|
||
|
||
> 递归法:
|
||
|
||
```javascript
|
||
/**
|
||
* Definition for a binary tree node.
|
||
* function TreeNode(val, left, right) {
|
||
* this.val = (val===undefined ? 0 : val)
|
||
* this.left = (left===undefined ? null : left)
|
||
* this.right = (right===undefined ? null : right)
|
||
* }
|
||
*/
|
||
/**
|
||
* @param {TreeNode} root1
|
||
* @param {TreeNode} root2
|
||
* @return {TreeNode}
|
||
*/
|
||
var mergeTrees = function (root1, root2) {
|
||
const preOrder = (root1, root2) => {
|
||
if (!root1)
|
||
return root2
|
||
if (!root2)
|
||
return root1;
|
||
root1.val += root2.val;
|
||
root1.left = preOrder(root1.left, root2.left);
|
||
root1.right = preOrder(root1.right, root2.right);
|
||
return root1;
|
||
}
|
||
return preOrder(root1, root2);
|
||
};
|
||
```
|
||
> 迭代法:
|
||
|
||
```javascript
|
||
|
||
/**
|
||
* Definition for a binary tree node.
|
||
* function TreeNode(val, left, right) {
|
||
* this.val = (val===undefined ? 0 : val)
|
||
* this.left = (left===undefined ? null : left)
|
||
* this.right = (right===undefined ? null : right)
|
||
* }
|
||
*/
|
||
/**
|
||
* @param {TreeNode} root1
|
||
* @param {TreeNode} root2
|
||
* @return {TreeNode}
|
||
*/
|
||
var mergeTrees = function(root1, root2) {
|
||
if (root1 === null) return root2;
|
||
if (root2 === null) return root1;
|
||
|
||
let queue = [];
|
||
queue.push(root1);
|
||
queue.push(root2);
|
||
while (queue.length) {
|
||
let node1 = queue.shift();
|
||
let node2 = queue.shift();;
|
||
node1.val += node2.val;
|
||
if (node1.left !== null && node2.left !== null) {
|
||
queue.push(node1.left);
|
||
queue.push(node2.left);
|
||
}
|
||
if (node1.right !== null && node2.right !== null) {
|
||
queue.push(node1.right);
|
||
queue.push(node2.right);
|
||
}
|
||
if (node1.left === null && node2.left !== null) {
|
||
node1.left = node2.left;
|
||
}
|
||
if (node1.right === null && node2.right !== null) {
|
||
node1.right = node2.right;
|
||
}
|
||
}
|
||
return root1;
|
||
};
|
||
|
||
```
|
||
|
||
### TypeScript
|
||
|
||
> 递归法:
|
||
|
||
```typescript
|
||
function mergeTrees(root1: TreeNode | null, root2: TreeNode | null): TreeNode | null {
|
||
if (root1 === null) return root2;
|
||
if (root2 === null) return root1;
|
||
const resNode: TreeNode = new TreeNode(root1.val + root2.val);
|
||
resNode.left = mergeTrees(root1.left, root2.left);
|
||
resNode.right = mergeTrees(root1.right, root2.right);
|
||
return resNode;
|
||
};
|
||
```
|
||
|
||
> 迭代法:
|
||
|
||
```typescript
|
||
function mergeTrees(root1: TreeNode | null, root2: TreeNode | null): TreeNode | null {
|
||
if (root1 === null) return root2;
|
||
if (root2 === null) return root1;
|
||
const helperQueue1: TreeNode[] = [],
|
||
helperQueue2: TreeNode[] = [];
|
||
helperQueue1.push(root1);
|
||
helperQueue2.push(root2);
|
||
let tempNode1: TreeNode,
|
||
tempNode2: TreeNode;
|
||
while (helperQueue1.length > 0) {
|
||
tempNode1 = helperQueue1.shift()!;
|
||
tempNode2 = helperQueue2.shift()!;
|
||
tempNode1.val += tempNode2.val;
|
||
if (tempNode1.left !== null && tempNode2.left !== null) {
|
||
helperQueue1.push(tempNode1.left);
|
||
helperQueue2.push(tempNode2.left);
|
||
} else if (tempNode1.left === null) {
|
||
tempNode1.left = tempNode2.left;
|
||
}
|
||
if (tempNode1.right !== null && tempNode2.right !== null) {
|
||
helperQueue1.push(tempNode1.right);
|
||
helperQueue2.push(tempNode2.right);
|
||
} else if (tempNode1.right === null) {
|
||
tempNode1.right = tempNode2.right;
|
||
}
|
||
}
|
||
return root1;
|
||
};
|
||
```
|
||
|
||
### Scala
|
||
|
||
递归:
|
||
```scala
|
||
object Solution {
|
||
def mergeTrees(root1: TreeNode, root2: TreeNode): TreeNode = {
|
||
if (root1 == null) return root2 // 如果root1为空,返回root2
|
||
if (root2 == null) return root1 // 如果root2为空,返回root1
|
||
// 新建一个节点,值为两个节点的和
|
||
var node = new TreeNode(root1.value + root2.value)
|
||
// 往下递归
|
||
node.left = mergeTrees(root1.left, root2.left)
|
||
node.right = mergeTrees(root1.right, root2.right)
|
||
node // 返回node,return关键字可以省略
|
||
}
|
||
}
|
||
```
|
||
|
||
迭代:
|
||
```scala
|
||
object Solution {
|
||
import scala.collection.mutable
|
||
def mergeTrees(root1: TreeNode, root2: TreeNode): TreeNode = {
|
||
if (root1 == null) return root2
|
||
if (root2 == null) return root1
|
||
var stack = mutable.Stack[TreeNode]()
|
||
// 先放node2再放node1
|
||
stack.push(root2)
|
||
stack.push(root1)
|
||
while (!stack.isEmpty) {
|
||
var node1 = stack.pop()
|
||
var node2 = stack.pop()
|
||
node1.value += node2.value
|
||
if (node1.right != null && node2.right != null) {
|
||
stack.push(node2.right)
|
||
stack.push(node1.right)
|
||
} else {
|
||
if(node1.right == null){
|
||
node1.right = node2.right
|
||
}
|
||
}
|
||
if (node1.left != null && node2.left != null) {
|
||
stack.push(node2.left)
|
||
stack.push(node1.left)
|
||
} else {
|
||
if(node1.left == null){
|
||
node1.left = node2.left
|
||
}
|
||
}
|
||
}
|
||
root1
|
||
}
|
||
}
|
||
```
|
||
|
||
### Rust
|
||
|
||
递归:
|
||
|
||
```rust
|
||
use std::cell::RefCell;
|
||
use std::rc::Rc;
|
||
impl Solution {
|
||
pub fn merge_trees(
|
||
root1: Option<Rc<RefCell<TreeNode>>>,
|
||
root2: Option<Rc<RefCell<TreeNode>>>,
|
||
) -> Option<Rc<RefCell<TreeNode>>> {
|
||
if root1.is_none() {
|
||
return root2;
|
||
}
|
||
if root2.is_none() {
|
||
return root1;
|
||
}
|
||
let binding = root1.clone();
|
||
let mut node1 = binding.as_ref().unwrap().borrow_mut();
|
||
let node2 = root2.as_ref().unwrap().borrow_mut();
|
||
node1.left = Self::merge_trees(node1.left.clone(), node2.left.clone());
|
||
node1.right = Self::merge_trees(node1.right.clone(), node2.right.clone());
|
||
node1.val += node2.val;
|
||
|
||
root1
|
||
}
|
||
}
|
||
```
|
||
|
||
迭代:
|
||
|
||
```rust
|
||
impl Solution {
|
||
pub fn merge_trees(
|
||
root1: Option<Rc<RefCell<TreeNode>>>,
|
||
root2: Option<Rc<RefCell<TreeNode>>>,
|
||
) -> Option<Rc<RefCell<TreeNode>>> {
|
||
if root1.is_none() {
|
||
return root2;
|
||
}
|
||
if root2.is_none() {
|
||
return root1;
|
||
}
|
||
let mut stack = vec![];
|
||
stack.push(root2);
|
||
stack.push(root1.clone());
|
||
while !stack.is_empty() {
|
||
let node1 = stack.pop().unwrap().unwrap();
|
||
let node2 = stack.pop().unwrap().unwrap();
|
||
let mut node1 = node1.borrow_mut();
|
||
let node2 = node2.borrow();
|
||
node1.val += node2.val;
|
||
if node1.left.is_some() && node2.left.is_some() {
|
||
stack.push(node2.left.clone());
|
||
stack.push(node1.left.clone());
|
||
}
|
||
if node1.right.is_some() && node2.right.is_some() {
|
||
stack.push(node2.right.clone());
|
||
stack.push(node1.right.clone());
|
||
}
|
||
if node1.left.is_none() && node2.left.is_some() {
|
||
node1.left = node2.left.clone();
|
||
}
|
||
if node1.right.is_none() && node2.right.is_some() {
|
||
node1.right = node2.right.clone();
|
||
}
|
||
}
|
||
root1
|
||
}
|
||
}
|
||
```
|
||
|
||
<p align="center">
|
||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||
</a>
|
||
|