617. 合并二叉树
题目链接:
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。
解题思路
该题就是需要同时遍历两棵树,可以采取“递归法”或者“迭代法”实现。
递归法
-
确定递归函数的参数和返回值
需要对两颗树进行合并,那参数就是两棵树的根节点,最后返回合并之后的树的根节点
-
确定终止条件
传入的是两棵树,那么当 root1 为空时,合并树就是 root2 (不论 root2 是否为空,为空返回空即可)
相反,当 root2 为空时,合并树就是 root1 (不论 root1 是否为空,为空返回空即可)
-
确定单层递归的逻辑
可以修改 root1 的结构使其成为 合并树,也可以重新构建一颗独立的 新树。递归生成 合并树 的左子树,右子树
代码(C++)
//递归 class Solution1 { public: TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) { // 如果 root1 为空,返回 root2 if (root1 == nullptr) return root2; // 如果 root2 为空,返回 root1 if (root2 == nullptr) return root1; //没有修改原来的两棵树,新建了一颗树 int sumVal = root1->val + root2->val; TreeNode* node = new TreeNode(sumVal); //中 node->left = mergeTrees(root1->left, root2->left); //左 node->right = mergeTrees(root1->right, root2->right); //右 return node; } }; //递归 class Solution2 { public: TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) { if (root1 == nullptr) return root2; if (root2 == nullptr) return root1; //直接修改 树1 root1->val += root2->val; root1->left = mergeTrees(root1->left, root2->left); //左 root1->right = mergeTrees(root1->right, root2->right); //右 return root1; } };
代码(JavaScript)
/** * @param {TreeNode} root1 * @param {TreeNode} root2 * @return {TreeNode} */ //递归 var mergeTrees = function(root1, 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; };
迭代法
借助队列实现迭代
-
两颗树的左节点都不为 null,就把将他们放入队列中;
-
两棵树的右节点都不为 null,也将他们放入队列中。
-
然后我们不断的从队列中取出节点,将节点的值相加。
-
如果出现 root1 的 left 节点为 null,root2 的 left 不为 null,直接将root2 的 left 赋给root1就可以了;
-
同理如果root1的 right 节点为 null,root2 的right不为 null,将root2 的 right 节点赋给root1即可。
代码(C++)
//迭代(队列,层序) class Solution3 { public: TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) { queue<TreeNode*> nodeQue; if (root1 == nullptr) return root2; if (root2 == nullptr) return root1; nodeQue.push(root1); nodeQue.push(root2); while (!nodeQue.empty()) { TreeNode* node1 = nodeQue.front(); nodeQue.pop(); TreeNode* node2 = nodeQue.front(); nodeQue.pop(); //此时两个节点一定不为空,值相加 node1->val += node2->val; //如果两个节点的左子树都不为空,加入队列 if (node1->left != nullptr && node2->left != nullptr) { nodeQue.push(node1->left); nodeQue.push(node2->left); } //如果两个节点的右子树都不为空,加入队列 if (node1->right != nullptr && node2->right != nullptr) { nodeQue.push(node1->right); nodeQue.push(node2->right); } //如果 节点1 的左子树为空,节点2 的左子树不为空,则将 节点2 赋值给 节点1 if (node1->left == nullptr && node2->left != nullptr) { node1->left = node2->left; } //如果 节点1 的右子树为空,节点2 的右子树不为空,则将 节点2 赋值给 节点1 if (node1->right == nullptr && node2->right != nullptr) { node1->right = node2->right; } } return root1; } };
代码(JavaScript)
/** * @param {TreeNode} root1 * @param {TreeNode} root2 * @return {TreeNode} */ //迭代 var mergeTrees = function(root1, root2) { if (root1 === null) return root2; if (root2 === null) return root1; let nodeQue = []; nodeQue.push(root1); nodeQue.push(root2); while (nodeQue.length != 0) { let node1 = nodeQue.shift(); let node2 = nodeQue.shift(); node1.val += node2.val; if (node1.left != null && node2.left != null) { nodeQue.push(node1.left); nodeQue.push(node2.left); } if (node1.right != null && node2.right != null) { nodeQue.push(node1.right); nodeQue.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; };