236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
这个题目先看懂官方题解
就是有两种可能
-
一种就是如果当前节点就是最近的公共节点,那么这个节点的右子树和左子树分别都有一个参数(q|p)
-
一种就是当前节点就是参数中的一个,假设是q,那么存在的情况就是,另一个p可能存在q节点的左子树也可能存在这个节点的右子树上
然后我们需要用到的方法就是递归啦
左右节点记录一下
const lson = dfs(root.left, p, q)
const rson = dfs(root.right, p, q)
整个的判断一遍
if ((lson && rson) || (root.val === p.val || root.val === q.val) && (lson || rson)) {
ans = root;
}
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
let ans;
const dfs = (root, p, q) => {
if (root === null) return false;
const lson = dfs(root.left, p, q)
const rson = dfs(root.right, p, q)
if ((lson && rson) || (root.val === p.val || root.val === q.val) && (lson || rson)) {
ans = root;
}
return lson || rson || (root.val === p.val || root.val === q.val)
}
dfs(root, p, q)
return ans;
};
下面有两道路径总和的题,一道题是只需要判断是否存在一条路径的总和为targetSum 还有一道题是需要将所有满足和的路径打印出来
都是用的递归
但这里有需要注意的一个就是,递归什么时候需要返回值什么时候不需要。
如果是找某条满足的路径就可以,就需要返回值,true或者false来判断是否需要继续递归下去
如果是整个树都需要递归,那么就不需要返回值
112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。
叶子节点 是指没有子节点的节点。
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {boolean}
*/
var hasPathSum = function(root, targetSum) {
if (root === null) return false
if (root.right === null && root.left === null) {
return targetSum - root.val == 0
}
return hasPathSum(root.left, targetSum- root.val) || hasPathSum(root.right, targetSum - root.val)
};
113. 路径总和 II
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
- 到叶子节点了,刚好也找到一条路径了
- 到叶子节点了,但是还没有找到
- node.left
if(root.left) {
path.push(root.left.val)
dfs(root.left,cnt - root.left.val,path)
path.pop()
}
- node.right
if(root.right) {
path.push(root.right.val)
dfs(root.right,cnt - root.right.val,path)
path.pop()
}
path.pop()是回溯, 如果到了某条叶子节点的值还没达到所需要的值。就向上回溯
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {number[][]}
*/
var pathSum = function(root, targetSum) {
let res = [];
const dfs = (root,cnt,path) => {
// 1
if (cnt === 0 && !root.right && !root.left) {
res.push([...path])
return
}
// 2
if (!root.right && !root.left) {
return ;
}
// 3
if(root.left) {
path.push(root.left.val)
dfs(root.left,cnt - root.left.val,path)
path.pop()
}
// 4
if(root.right) {
path.push(root.right.val)
dfs(root.right,cnt - root.right.val,path)
path.pop()
}
return
}
if (root === null) return []
dfs(root,targetSum - root.val,[root.val])
return res
};