1.关于二叉树最近公共祖先的问题
在看文章前可以做一下这道力扣题:[236. 二叉树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/description/)
对我而言,刷力扣是为了面对面试,而不是参加算法竞赛,所以说重要的是分析问题,理清思路而不是必须要把题解照搬。并且,关于树这一块我更喜欢使用递归的方式去解决问题,所以已递归思考的角度切入问题。
问题的核心是什么?
是不是需要去找到这棵树最低的最近公共祖先,怎么找?这里就使用递归去遍历树同时根据子树的情况去判断是否是公共祖先。
以下的模版适用于绝大数关于二叉树的题。
func solution(root *TreeNode) 返回结果 {
if root == nil {
return 结果
}
// 递归处理左子树
left := solution(root.Left)
// 递归处理右子树
right := solution(root.Right)
// 处理当前节点并返回结果
return mergeResults(left, right)
}
示例:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
按以上的模版,那么我们思考怎么确定这个祖先呢?如果说当前节点的左右子树都存在p、q,那么这个node就是最近公共祖先;如果左边不存在,那么就递归遍历右子树,反之依然。
从根节点开始判断,递归往下深入,最后回溯时确定公共祖先。
判断当前节点:
- 如果当前节点是
nil
,说明这条路径找不到目标,返回nil
。 - 如果当前节点是
p
或q
,说明找到了一个目标节点,返回当前节点。
递归遍历左右子树:
然后,分别递归查找左子树和右子树,返回左右子树的结果。
判断左右子树的结果:
- 如果左右子树都找到了目标节点,说明当前节点是最近公共祖先,返回当前节点。
- 如果只有一侧找到目标节点,说明公共祖先在这一侧,返回该侧的结果。
2.二叉树合并问题
力扣题目链接:617. 合并二叉树https://leetcode.cn/problems/merge-two-binary-trees/description/
题目
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
}
合并两个树,其实也就是遍历其中一棵树,然后对其的Val进行相加。
确定判断条件:root1==nil || root2==nil -> return nil
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
root1.Val += root2.Val
root1.Left = mergeTrees(root1.Left, root2.Left)
root1.Right = mergeTrees(root1.Right, root2.Right)
return root1
}