LeedCode 617: merge binary trees

Posted by fsumba on Sat, 22 Jan 2022 11:41:53 +0100

Path sum

Title Description:

Given two binary trees, imagine that when you overlay one of them on the other, some nodes of the two binary trees will overlap.

You need to merge them into a new binary tree. The merging rule is that if two nodes overlap, their values are added as the new value after node merging. Otherwise, the node that is not NULL will be directly used as the node of the new binary tree.

Example 1:

Input:
    Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
Output:
Merged tree:
         3
        / \
       4   5
      / \   \ 
     5   4   7 

Link:

617. Merged binary tree LeetCode (LeetCode CN. Com)

Problem solving ideas

Idea 1: recursion / depth first traversal

You can merge two binary trees using depth first search. Start from the root node, traverse two binary trees at the same time, and merge the corresponding nodes.

The corresponding nodes of two binary trees may exist in the following three cases, and different merging methods are used for each case.

  • If the corresponding nodes of two binary trees are empty, the corresponding nodes of the merged binary tree are also empty;
  • If only one of the corresponding nodes of two binary trees is empty, the corresponding node of the merged binary tree is a non empty node;
  • If the corresponding nodes of the two binary trees are not empty, the value of the corresponding node of the merged binary tree is the sum of the values of the corresponding nodes of the two binary trees. In this case, it is necessary to explicitly merge the two nodes.

After merging a node, merge the left and right subtrees of the node respectively. This is a recursive process

/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {TreeNode}
 */
var mergeTrees = function (root1, root2) {
  if (root1 === null) {
    return root2;
  }
  if (root2 === null) {
    return root1;
  }
  var mergeNode = new TreeNode(root1.val + root2.val);
  mergeNode.left = mergeTrees(root1.left, root2.left);
  mergeNode.right = mergeTrees(root1.right, root2.right);

  return mergeNode;
};

Time complexity: O(min(m,n)), where m and N are the number of nodes of two binary trees respectively. The depth first search is performed on two binary trees at the same time. Only when the corresponding nodes in the two binary trees are not empty will the explicit merge operation be performed on the node. Therefore, the number of nodes accessed will not exceed the number of nodes in the smaller binary tree

Spatial complexity: O(min(m,n)), where m and N are the number of nodes of two binary trees respectively. The spatial complexity depends on the number of layers of recursive calls. The number of layers of recursive calls will not exceed the maximum height of the smaller binary tree. In the worst case, the height of the binary tree is equal to the number of nodes.

Idea 2: breadth first search

You can also use breadth first search to merge two binary trees. First, judge whether the two binary trees are empty. If both binary trees are empty, the merged binary tree is also empty. If only one binary tree is empty, the merged binary tree is another non empty binary tree.

If both binary trees are not empty, first calculate the value of the merged root node, then start breadth first search from the root node of the merged binary tree and the two original binary trees, traverse each binary tree from the root node at the same time, and merge the corresponding nodes.

Three queues are used to store the nodes of the merged binary tree and the nodes of the two original binary trees. Initially, the root node of each binary tree is added to the corresponding queue. Take out one node from each queue at a time and judge whether the left and right child nodes of the nodes of the two original binary trees are empty. If the left child node of at least one of the current nodes of the two original binary trees is not empty, the left child node of the corresponding node of the merged binary tree is not empty. The same is true for the right child node.

If the left child node of the merged binary tree is not empty, you need to calculate the left child node of the merged binary tree and the whole left child tree according to the left child nodes of the two original binary trees. Consider the following two situations:

  • If the left child nodes of the two original binary trees are not empty, the value of the left child nodes of the merged binary tree is the sum of the values of the left child nodes of the two original binary trees. After creating the left child nodes of the merged binary tree, the left child nodes in each binary tree are added to the corresponding queue;
  • If one of the left sub nodes of two original binary trees is empty, that is, the left sub tree of one original binary tree is empty, the left sub tree of the merged binary tree is the left sub tree of the other original binary tree. At this time, it is not necessary to continue traversing the non empty left sub tree, so it is not necessary to add the left sub node to the queue.

For the right sub node and right sub tree, the processing method is the same as that of the left sub node and left sub tree

var mergeTrees = function (root1, root2) {
  if (root1 === null) {
    return root2;
  }
  if (root2 === null) {
    return root1;
  }
  var mergeNode = new TreeNode(root1.val + root2.val);
  var queue = [mergeNode],
    queue1 = [root1],
    queue2 = [root2];
  while (queue1.length && queue2.length) {
    var node = queue.pop(),
      node1 = queue1.pop(),
      node2 = queue2.pop();
    var left1 = node1.left,
      left2 = node2.left,
      right1 = node1.right,
      right2 = node2.right;
    if (left1 != null || left2 != null) {
      if (left1 != null && left2 != null) {
        var left = new TreeNode(left1.val + left2.val);
        node.left = left;
        queue.push(left);
        queue1.push(left1);
        queue2.push(left2);
      } else if (left1 != null) {
        node.left = left1;
      } else if (left2 != null) {
        node.left = left2;
      }
    }
    if (right1 != null || right2 != null) {
      if (right1 != null && right2 != null) {
        var right = new TreeNode(right1.val + right2.val);
        node.right = right;
        queue.push(right);
        queue1.push(right1);
        queue2.push(right2);
      } else if (right1 != null) {
        node.right = right1;
      } else {
        node.right = right2;
      }
    }
  }
  return mergeNode;
};

Time complexity: O(min(m,n)), where m and N are the number of nodes of two binary trees respectively. Carry out breadth first search on two binary trees at the same time. Only when the corresponding nodes in the two binary trees are not empty can the node be accessed. Therefore, the number of nodes accessed will not exceed the number of nodes of the smaller binary tree.

Spatial complexity: O(min(m,n)), where m and N are the number of nodes of two binary trees respectively. The spatial complexity depends on the number of elements in the queue. The number of elements in the queue will not exceed the number of nodes of the smaller binary tree.

 

Topics: Binary tree LeedCode