JZ84 二叉树中和为某一值的路径(三)
(中等)
题目
描述
给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum 。
1.该题路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点
2.总节点数目为n
3.保证最后返回的路径个数在整形范围内(即路径个数小于231-1)
假如二叉树root为{1,2,3,4,5,4,3,#,#,-1},sum=6,那么总共如下所示,有3条路径符合要求
示例1
输入:
{1,2,3,4,5,4,3,#,#,-1},6
返回值:
3
说明:
如图所示,有3条路径符合
示例2
输入:
{0,1},1
返回值:
2
示例3
输入:
{1,#,2,#,3},3
返回值:
2
思路
此题与之前一道剑指 Offer 的题目十分相似(可见我之前的文章中的第二道题:【算法】解题总结:剑指 Offer 33 二叉搜索树的后序遍历序列、剑指 Offer 34 二叉树中和为某一值的路径),此题是在之前一道题的条件上,放宽了要求,即路径定义不需要从根节点开始,也不需要在叶子节点结束,而不是之前的必须从根结点开始,到叶子结点结束,因此,此题的情况必然会更多,这两道题可以类比做,但不要混淆。
总体思路与上述的文章中第二道题的思路大体一致,此题只需要再进行一组递归即可,也就是初始结点的递归,这也是一道典型的回溯算法题目,此题只需不断递归选取初始结点的同时,在内部再递归进行当前初始结点开始的路径的选择,我认为递归回溯的题目直接看代码更加易懂,文字描述不易表述思想,因此不再赘述。
实现
public class JZ84二叉树中和为某一值的路径2 {
int count = 0;
public int FindPath (TreeNode root, int sum) {
if (root == null) return count;
backtrackTraversal(root, sum);
FindPath(root.left, sum);
FindPath(root.right, sum);
return count;
}
public void backtrackTraversal(TreeNode node, int remainNum) {
if (node == null) return;
remainNum -= node.val;
if (remainNum == 0) count++; //找到一条路径
backtrackTraversal(node.left, remainNum);
backtrackTraversal(node.right, remainNum);
}
}
JZ82 二叉树中和为某一值的路径(一)
(简单)
题目
描述
给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
示例1
输入:
{5,4,8,1,11,#,9,#,#,2,7},22
返回值:
true
示例2
输入:
{1,2},0
返回值:
false
示例3
输入:
{1,2},3
返回值:
true
示例4
输入:
{},0
返回值:
false
思路
此题与上一题类似,只是路径定义为从树的根结点开始往下一直到叶子结点所经过的结点,属于上面题目的变式,只需更改返回结果不再是总路线数,而是是否大于 0 即可,即路径是否存在。
实现
public class Solution {
int count = 0;
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false;
backtrackTraversal(root, sum);
return count > 0;
}
public void backtrackTraversal(TreeNode node, int remainNum) {
if (node == null || count > 0) return;
remainNum -= node.val;
if (remainNum == 0 && node.left == null && node.right == null) count++; //找到一条路径
backtrackTraversal(node.left, remainNum);
backtrackTraversal(node.right, remainNum);
}
}