二叉树中和为某一值的路径(一)
题目:给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。(难度:简单)
要求:
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
例子:
思路:
因为只能由根节点到叶子节点的顺序,所以本题采用先序遍历的方式进行求解。
算法步骤:
1、判断根是否为空,空则直接返回false
2、判断是否为叶子节点且sum是否等于该节点的值(因为递归每次传的值是 sum - root.val
),是则返回true
3、对左子树进行递归,对右子树进行递归,如果有满足条件,则会返回true
代码:
/*
* function TreeNode(x) {
* this.val = x;
* this.left = null;
* this.right = null;
* }
*/
/**
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
function hasPathSum( root , sum ) {
// write code here
if(root === null){
return false
}
if(root.left === null && root.right === null && root.val === sum){
return true
}
return hasPathSum(root.left,sum - root.val) || hasPathSum(root.right,sum - root.val)
}
module.exports = {
hasPathSum : hasPathSum
};
二叉树中和为某一值的路径(二)
题目:输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。(难度:中等)
要求:
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
例子:
思路:
本题对上题难度进行提升,需要我们寻找出所有的路径,依旧采用先序遍历的方式进行求解。
算法步骤:
1、先初始化两个数组(res
和path
),res
为结果数组,path
为每次的路径数组。
2、编写一个函数,用来递归寻找路径的。
3、(1)递归终止条件:先判断根是否为空,空的话进行return
回溯。(2)对当前节点进行处理。先加入到路径数组,计算所需值sum -= root.val
,如果该节点为叶子节点并且sum == 0
,说明找到一条路径了,添加到res
数组。(3)左右子树递归。recur(root.left, sum); recur(root.right, sum);
4、当执行到path.pop();
时,说明该节点是叶子节点但计算后的sum
不等于0,需要返回到前一个节点,所以要将当前节点进行弹栈操作。
5、最后返回res
结果数组
代码:
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function FindPath(root, expectNumber)
{
// write code here
let res = [];
let path = [];
// 先序遍历,回溯算法
function recur(root,sum) {
if(root == null) {
return;
}
// path记录当前路径各结点的val
path.push(root.val);
sum -= root.val;
// 如果符合要求,将当前path加入res数组
if (sum == 0 && root.left == null && root.right == null) {
res.push(path.slice(0));
// 因为path数组是一个对象,需要深拷贝
}
recur(root.left, sum);
recur(root.right, sum);
path.pop();
}
recur(root, expectNumber);
return res;
}
module.exports = {
FindPath : FindPath
};
二叉树中和为某一值的路径(三)
题目:给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum 。(难度:中等)
要求:
1.该题路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点
2.总节点数目为n
3.保证最后返回的路径个数在整形范围内(即路径个数小于2^31-1)
例子:
思路:
本题较上面两题,条件放宽了,并不是从根节点到叶子节点了,而是从每个节点到叶子节点进行寻找所有满足条件的路径个数。
算法步骤:
1、编写两个函数,深度优先遍历函数dfs(root,sum)
和查找函数find(root,sum)
,并初始化count
为0
2、dfs
函数编写:(1)递归结束条件:当前节点为null
,进行return
返回。(2)处理该节点。先用sum -= root.val
计算剩余值,当剩余值为0,说明找到了一条路径,count++
(3)对该节点的左子树和右子树进行递归操作。
3、find
函数编写:(1)如果根节点为空,就不用查找了,直接返回0。(2)调用dfs
函数计算以当前结点作为起点满足条件的路径个数(3)递归计算以当前结点的左孩子作为起点的满足条件的路径个数和以右孩子作为起点的满足条件的路径个数。
代码:
// function TreeNode(x) {
// this.val = x;
// this.left = null;
// this.right = null;
// }
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param sum int整型
* @return int整型
*/
function FindPath( root , sum ) {
// write code here
let count = 0
function dfs(root,sum){
if(root === null){
return
}
sum -= root.val
if(sum === 0){
count++
}
dfs(root.left,sum)
dfs(root.right,sum)
}
function find(root,sum){
if(root === null){
return 0
}
dfs(root,sum)
find(root.left,sum)
find(root.right,sum)
}
find(root,sum)
return count
}
module.exports = {
FindPath : FindPath
};