You are given two binary trees root1 and root2.
Imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge the two trees into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of the new tree.
Return the merged tree.
Note: The merging process must start from the root nodes of both trees.
Example 1:
Input: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
Output: [3,4,5,5,4,null,7]Example 2:
Input: root1 = [1], root2 = [2]
Output: [3]Example 3:
Input: root1 = [], root2 = [2]
Output: [2]Constraints:
0 <= The number of nodes in both the trees <= 2000.-10,000 <= Node.val <= 10,000Before attempting this problem, you should be comfortable with:
To merge two trees, we traverse both trees simultaneously. At each position, if both trees have a node, we create a new node with the sum of their values. If only one tree has a node at a position, we use that node's value. We recursively build the left and right subtrees the same way. This approach creates an entirely new tree without modifying the inputs.
root1 and root2 are null, return null.0 if the node is null).root.left.root.right.# 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: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1 and not root2:
return None
v1 = root1.val if root1 else 0
v2 = root2.val if root2 else 0
root = TreeNode(v1 + v2)
root.left = self.mergeTrees(root1.left if root1 else None, root2.left if root2 else None)
root.right = self.mergeTrees(root1.right if root1 else None, root2.right if root2 else None)
return rootWhere and are the number of nodes in the given trees.
Instead of creating new nodes, we can modify the first tree in place. If one tree is missing at a position, we simply return the other tree's subtree. If both exist, we add the second tree's value to the first tree's node and recursively merge the children. This saves memory by reusing existing nodes.
root1 is null, return root2.root2 is null, return root1.root2.val to root1.val.root1.left.root1.right.root1.# 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: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
root1.val += root2.val
root1.left = self.mergeTrees(root1.left, root2.left)
root1.right = self.mergeTrees(root1.right, root2.right)
return root1Where and are the number of nodes in the given trees.
We can avoid recursion by using an explicit stack to traverse both trees. We push triplets of (node1, node2, merged_node) onto the stack. For each triplet, we create children for the merged node based on whether the corresponding children exist in either input tree. This creates a new tree while simulating the recursive approach iteratively.
null.root1, root2, root).node1, node2, node).# 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: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
root = TreeNode(root1.val + root2.val)
stack = [(root1, root2, root)]
while stack:
node1, node2, node = stack.pop()
if node1.left and node2.left:
node.left = TreeNode(node1.left.val + node2.left.val)
stack.append((node1.left, node2.left, node.left))
elif not node1.left:
node.left = node2.left
else:
node.left = node1.left
if node1.right and node2.right:
node.right = TreeNode(node1.right.val + node2.right.val)
stack.append((node1.right, node2.right, node.right))
elif not node1.right:
node.right = node2.right
else:
node.right = node1.right
return rootWhere and are the number of nodes in the given trees.
Similar to the recursive in-place approach, we can modify the first tree iteratively using a stack. We push pairs of nodes from both trees. When both nodes exist, we add values and continue processing children. If only one tree has a child at a position, we directly attach that subtree to the first tree. This avoids creating new nodes.
null.root1, root2).node1, node2). Skip if either is null.node2.val to node1.val.node1 has no left child, attach node2.left.root1.# 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: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
stack = [(root1, root2)]
while stack:
node1, node2 = stack.pop()
if not node1 or not node2:
continue
node1.val += node2.val
if node1.left and node2.left:
stack.append((node1.left, node2.left))
elif not node1.left:
node1.left = node2.left
if node1.right and node2.right:
stack.append((node1.right, node2.right))
elif not node1.right:
node1.right = node2.right
return root1Where and are the number of nodes in the given trees.
When one of the input trees is null at a position while the other is not, you should return the non-null subtree directly. Failing to handle this base case properly leads to null pointer exceptions or missing nodes in the result.
When using the in-place approach, the first tree is modified to become the merged result. If the original trees need to be preserved for other purposes, this causes unexpected side effects. Use the approach that creates a new tree if the inputs must remain unchanged.