路径总和(IIIIII)| 树

Posted 桃陉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了路径总和(IIIIII)| 树相关的知识,希望对你有一定的参考价值。

1.路径总和I

题 目 描 述 \\colorViolet题目描述

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。(叶子节点 是指没有子节点的节点。)

示例一:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例二:

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

题目链接leetcode

解 题 思 路 \\colorViolet解题思路

∙ \\bullet 广搜(BFS):使用队列作为数据结构。一个队列用来存放二叉树结点,另一个队列存放根结点到当前结点的路径总和。当找到符合条件的路径总和后便可以退出。

∙ \\bullet 递归(深搜):先从根结点搜索一条路径到底,不符合条件后便后退一步,然后继续进行搜索。

代 码 ( C + + ) \\colorViolet代码(C++) C++

∙ \\bullet BFS

class Solution 
public:
    bool hasPathSum(TreeNode* root, int sum) 
        queue<TreeNode*> q;  //存放结点队列
        queue<int> que;    //存放路径长度队列
        if(root==NULL) return false;   //判空
        q.push(root);   //初始化,向两个队列中加入根结点信息
        que.push(root->val);
 
        while(!q.empty())    //非空继续
        
            for(int i=q.size();i>0;i--)   //一层一层循环
            
                TreeNode* temp=q.front();  //取出第一个元素信息并出队
                int num=que.front();
                if(!temp->left && !temp->right && num==sum) return true;  //判断是否为叶结点并且路径和未目标和
                 q.pop();
                que.pop();

                if(temp->left)    //若存在左子树,就把左子结点加入q中,把当前路径加入que中
                    q.push(temp->left);
                    que.push(num+temp->left->val);
                
                if(temp->right)   ///若存在右子树,就把右子结点加入q中,把当前路径加入que中
                    q.push(temp->right);
                    que.push(num+temp->right->val);
                
            
        
        return false;
    
;

∙ \\bullet DFS

class Solution 
public:
    bool hasPathSum(TreeNode* root, int targetSum) 
        //判空
        if(root==nullptr) return false;
        //如果是叶子结点并且总和相同返回true,不同返回false
        if(root->right==nullptr && root->left==nullptr) return targetSum == root->val;
        //调用该函数,每次将targetSum减去当前的结点值,最后判断是否等于叶结点的值
        return hasPathSum(root->left,targetSum-root->val) || hasPathSum(root->right,targetSum-root->val);
    
;

2.路径总和II

题 目 描 述 \\colorViolet题目描述
给你二叉树的根节点 root 和一个数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

示例一:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例二:

输入:root = [1,2,3], targetSum = 5
输出:[]

题目链接leetcode

解 题 思 路 \\colorViolet解题思路

递归:与上一题不同,本题我们需要找出所有路径之和等于目标值的具体路径。所以我们在搜索的过程中需要使用一个动态数组来记录当前的路径,当该条路径符合题意时将其存入最后返回的二维动态数组中即可。

代 码 ( C + + ) \\colorViolet代码(C++) C++

class Solution 
public:
    vector<vector<int>> res; //目标数组
    vector<int>ans;  //每次路径的数组
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) 
        findAllPath(root,targetSum);
        return res;
    
    void findAllPath(TreeNode* root,int targetSum)
    
        if(root==nullptr) return ;  //判空
        ans.emplace_back(root->val);  //加入ans数组
        targetSum -= root->val;  //当前的目标值
        //若为叶结点且符合题意那么输入到目标数组中
        if(root->left == nullptr && root->right == nullptr && targetSum ==0) res.emplace_back(ans);
        findAllPath(root->left,targetSum);
        findAllPath(root->right,targetSum);
        ans.pop_back();  //每次回退的时候删除最后一个数
    
;

3.路径总和III

题 目 描 述 \\colorViolet题目描述

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例一:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例二:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3

题目来源leetcode

解 题 思 路 \\colorViolet解题思路

递归:该题的路径是二叉树中随机向下的一部分,所以出发的结点也不是固定的根节点。这里我们只需要新建一个 findAllNum 函数用来计算以当前结点为根,向下的所有路径结果。然后在 pathSum 函数里面循环调用该函数即可。

代 码 ( C + + ) \\colorViolet代码(C++) C++

class Solution 
public:
    int res=0; //符合题意的路径数目
    int pathSum(TreeNode* root, int targetSum) 
        if(root==NULL) return 0;
        findAllNum(root,targetSum); //计算当前结点为根节点下满足的路径数目
        pathSum(root->left,targetSum); //以左子树结点为根
        pathSum(root->right,targetSum); //以右子树结点为根
        return res;    
    

    void findAllNum(TreeNode* root,int targetSum)
    
        if(root==NULL) return ;
        targetSum-=root->val;
        if(targetSum==0) res+=1;
        findAllNum(root->left,targetSum);
        findAllNum(root->right,targetSum);
    
;

以上是关于路径总和(IIIIII)| 树的主要内容,如果未能解决你的问题,请参考以下文章

树递归————路径总和

LeetCode-树路径总和 III

Leetcode——二叉树中和为某一值的路径(路径总和 II)

二叉树是否存在节点和为指定值的路径/路径总和Ⅱ

路径总和III---双dfs/哈希表记录二叉树前缀和

c_cpp 给定二叉树和总和,确定树是否具有根到叶路径,以便沿路径添加所有值等于gi