题目
题目的主要信息:
- 给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径
- 路径定义为从树的根节点开始往下一直到叶子节点所经过的节点
- 路径只能从父节点到子节点,不能从子节点到父节点
举一反三:
学习完本题的思路你可以解决如下题目:
方法一:递归(推荐使用)
知识点:二叉树递归
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。
而二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数不断进入子树。
思路:
既然是检查从根到叶子有没有一条等于目标值的路径,那肯定需要从根节点遍历到叶子,我们可以在根节点每次往下一层的时候,将sum减去节点值,最后检查是否完整等于0. 而遍历的方法我们可以选取二叉树常用的递归前序遍历,因为每次进入一个子节点,更新sum值以后,相当于对子树查找有没有等于新目标值的路径,因此这就是子问题,递归的三段式为:
- 终止条件: 每当遇到节点为空,意味着过了叶子节点,返回。每当检查到某个节点没有子节点,它就是叶子节点,此时sum减去叶子节点值刚好为0,说明找到了路径。
- 返回值: 将子问题中是否有符合新目标值的路径层层往上返回。
- 本级任务: 每一级需要检查是否到了叶子节点,如果没有则递归地进入子节点,同时更新sum值减掉本层的节点值。
具体做法:
- step 1:每次检查遍历到的节点是否为空节点,空节点就没有路径。
- step 2:再检查遍历到是否为叶子节点,且当前sum值等于节点值,说明可以刚好找到。
- step 3:检查左右子节点是否可以有完成路径的,如果任意一条路径可以都返回true,因此这里选用两个子节点递归的或。
Java实现代码:
import java.util.*;
public class Solution {
public boolean hasPathSum (TreeNode root, int sum) {
//空节点找不到路径
if(root == null)
return false;
//叶子节点,且路径和为sum
if(root.left == null && root.right == null && sum - root.val == 0)
return true;
//递归进入子节点
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
}
C++实现代码:
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
//空节点找不到路径
if(root == NULL)
return false;
//叶子节点,且路径和为sum
if(root->left