题目:[1]
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。
思路
同步遍历两个二叉树,并且将到的节点相加,和作为新二叉树的节点
每次遍历将新的二叉树作为子树追加到上一次生成的的二叉树中
特殊情况
两个二叉树,其中任意一个为 null,直接返回另外一个
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} t1
* @param {TreeNode} t2
* @return {TreeNode}
*/
var mergeTrees = function(t1, t2) {
if (t1 == null) return t2
if (t2 == null) return t1
function dfs(node1, node2) {
if (node1 == null) return node2
if (node2 == null) return node1
let node = new TreeNode(node1.val + node2.val)
// 追加二叉左子树
node.left = dfs(node1.left, node2.left)
// 追加二叉右子树
node.right = dfs(node1.right, node2.right)
return node
}
return dfs(t1, t2)
}
优化
给定的二叉树,后续不再适用,那么可以将任意取两个二叉树中的一个,在其上累计另外一个二叉树,最后返回那个二叉树,这样省略了每层生成新树的逻辑
var mergeTrees = function(t1, t2) {
if (t1 == null) return t2
if (t2 == null) return t1
function dfs(node1, node2) {
if (node1 == null) return node2
if (node2 == null) return node1
node1.val += node2.val
node1.left = dfs(node1.left, node2.left)
node1.right = dfs(node1.right, node2.right)
return node1
}
return dfs(t1, t2)
}
二叉树的遍历除了 DFS 还可以使用 BFS:
var mergeTrees = function(t1, t2) {
if (t1 == null) return t2
if (t2 == null) return t1
let root = new TreeNode(t1.val + t2.val),
queue = [root],
queue1 = [t1],
queue2 = [t2]
while (queue1.length && queue2.length) {
let node = queue.shift(),
node1 = queue1.shift(),
node2 = queue2.shift(),
left1 = node1.left,
left2 = node2.left,
right1 = node1.right,
right2 = node2.right
if (left1 != null || left2 != null) {
if (left1 != null && left2 != null) {
let 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) {
let 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 root
}
优化
参照上面的逻辑,不生产新树,在 t1 中做累计
var mergeTrees = function(t1, t2) {
if (t1 == null) return t2
if (t2 == null) return t1
let queue1 = [t1],
queue2 = [t2]
while (queue1.length && queue2.length) {
let node1 = queue1.shift(),
node2 = queue2.shift(),
left1 = node1.left,
left2 = node2.left,
right1 = node1.right,
right2 = node2.right
node1.val += node2.val
if (left1 != null || left2 != null) {
if (left1 != null && left2 != null) {
queue1.push(left1)
queue2.push(left2)
} else if (left2 != null) {
node1.left = left2
}
}
if (right1 != null || right2 != null) {
if (right1 != null && right2 != null) {
queue1.push(right1)
queue2.push(right2)
} else if (right2 != null) {
node1.right = right2
}
}
}
return t1
}