题目:二叉树中是否存在节点和为指定值的路径

描述:给定一个二叉树和一个值 sum,判断是否有从根节点到叶子节点的节点值之和等于 sum的路径,例如:给出如下的二叉树, sum=22,

返回true,因为存在一条路径5→4→11→2的节点值之和为22

示例1:输入:{1,2},0,返回值:false


解法一:

思路分析:首先我们通读题目可以知道,要计算节点和为指定路径,肯定需要进行遍历操作,将二叉树的元素进行遍历分为三种情况考虑:
第一种:当root == nullptr,即root都不存在,可直接返回false;

第二种:当root的值正好等于sum的值,且其左右子树均为空,直接返回true;

第三种:用sum的值减去root的值,继续在root的左右子树中进行遍历操作。

实例分析:如上图实例

5

4

8

1

11

9

2

7

将上述表格简述为树,sum的值为22,符合条件三,用sum22 - 5 = 17

其次,遍历左子树4,符合条件三,用sum17 - 4 = 13

遍历右子树11,符合条件三,用sum13 - 11 = 2

遍历左子树2,符合条件三,用sum2 - 2 = 0

递归操作,符合条件二,返回true


具体C++程序为:


/**
 * struct TreeNode {
 *    int val;
 *    struct TreeNode *left;
 *    struct TreeNode *right;
 * };
 */
 
class Solution {
public:
    /**
     *
     * @param root TreeNode类
     * @param sum int整型
     * @return bool布尔型
     */
    bool hasPathSum(TreeNode* root, int sum) {
        // write code here
        if(root == nullptr)
            return false;
        else if(root->val == sum && root->left == nullptr && root->right == nullptr)
            return true;
        return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right , sum - root->val);//继续遍历循环
    }
};


这个程序是从root的两边同时开始查找,只要有一方返回true,结果就直接返回true,所以其时间复杂度为O(N),空间复杂度为O(1)。

解法二:

思路分析:二叉树根节点到叶子结点和为指定值的路径,因为不需要保存每一条满足的路径,如果有一条路径满足指定值,就可以返回最终结果值true,我们使用一个flag变量表示是否找到满足题意的路径和,在遍历每一条路径的时候,遍历每一个结点,把当前结点的值加入到路径和当中,假如到叶子结点所求的路径等于sum,那么就将flag改为true。

具体C++代码为:


/**
 * struct TreeNode {
 *    int val;
 *    struct TreeNode *left;
 *    struct TreeNode *right;
 * };
 */
 
class Solution {
public:
    /**
     *
     * @param root TreeNode类
     * @param sum int整型
     * @return bool布尔型
     */
    bool flag = false;//全局变量
    bool hasPathSum(TreeNode* root, int sum) {
        // write code here、
        panduan(root, sum, 0);
        return flag;
    }
    void panduan(TreeNode* root,int sum,int add){
        if(root == nullptr || flag == true)
            return;
        add += root->val;//存储路径和
        if(root->left == NULL && root->right == NULL){
            if(sum == add)//是否与sum相等
                flag = true;
        }
        else{
            panduan(root->left,sum,add);//递归左子树
            panduan(root->right,sum,add);//递归右子树
        }
    }
};


该程序需要不断的递归左右子树,故时间复杂度为O(N),空间复杂度为O(N)。