LC-617. 合并二叉树

166 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

输入: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出: [3,4,5,5,4,null,7]

示例 2:

输入: root1 = [1], root2 = [1,2]
输出: [2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000] 内
  • -104 <= Node.val <= 104

题解

1.广度优先遍历

由于我们需要创建一个新的二叉树,所以我们需要进行收集

  • 首先跟据两个root1和root2来创建一个新树的 root

  • 再跟据两个 root1和root2 分别的left和right,来进行收集新树 left 和 right

  • 每次进行入队和出队操作,在内部进行收集

  • 结束条件为,直到两个队列中的其中一个为空

const mergeTrees = (root1, root2) => {
  // 两棵树的根节点
  if (root1 == null) return root2
  if (root2 == null) return root1

  // 两个根节点不为空的情况下,合并得到一个新的根节点 作为创建一个新的树
  // 新树的作用,就是收集
  let newTrees = new TreeNode(root1.val + root2.val)


  // 创建3个队列
  let queue = [newTrees],
    queue1 = [root1],
    queue2 = [root2]


  // 循环遍历
  while (queue1.length && queue2.length) {
    // 出队
    let node = queue.shift(),
      node1 = queue1.shift(),
      node2 = queue2.shift()

    // left 和 right
    let left1 = node1.left,
      left2 = node2.left,
      right1 = node1.right,
      right2 = node2.right

    // 判断left
    if (left1 || left2) {
      // 要合并俩节点有左子节点都非空
      if (left1 && left2) {
        // 合并并赋值为左子树
        let left = new TreeNode(left1.val + left2.val)
        // 收集 left
        node.left = left

        // 进入队列
        queue.push(left)
        queue1.push(left1)
        queue2.push(left2)
      } else node.left = left1 || left2
    }

    // 判断right
    if (right1 || right2) {
      if (right1 && right2) {
        let right = new TreeNode(right1.val + right2.val)
        // 收集 right
        node.right = right
        queue.push(right)
        queue1.push(right1)
        queue2.push(right2)
      } else node.right = right1 || right2
    }
  }
  
  return newTrees
}

1.深度优先遍历

可以看到深度优先遍历的递归优势,比广度优先遍历的队列模式要更清楚一点。

/**
 * 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)
 * }
 */
const mergeTrees = (root1, root2) => {
  // 其中一个节点为空时
  if (root1 == null) return root2
  if (root2 == null) return root1

  // 递归
  return new TreeNode(root1.val + root2.val, mergeTrees(root1.left, root2.left), mergeTrees(root1.right, root2.right))
}

总结

题目 12 :这道题用深度优先遍历的思路来解的话,还是不太难,但是对于广度优先遍历的思路就有点难理解,可以多加查看