路径总和(I、II、III)| 树

1.路径总和I

题 目 描 述 \color{Violet}题目描述

给你二叉树的根节点 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

解 题 思 路 \color{Violet}解题思路

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

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

代 码 ( C + + ) \color{Violet}代码(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

题 目 描 述 \color{Violet}题目描述
给你二叉树的根节点 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

解 题 思 路 \color{Violet}解题思路

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

代 码 ( C + + ) \color{Violet}代码(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

题 目 描 述 \color{Violet}题目描述

给定一个二叉树的根节点 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

解 题 思 路 \color{Violet}解题思路

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

代 码 ( C + + ) \color{Violet}代码(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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比奇堡咻飞兜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值