leetcode刷题(六)路径总和I、II、III

(一)112题

题目地址:https://leetcode-cn.com/problems/path-sum/description/

题目描述:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

解决方案:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(root==NULL){
            return false;
         }
        int t=sum-root->val;
        if(root->left==NULL&& root->right==NULL){
             return t==0 ? true :false;
        }  
        //递归调用函数,分别判断根结点的左节点和右节点
        return hasPathSum(root->left,t) || hasPathSum(root->right,t);
    }

};


备注:这里的解决方案,采用递归调用的形式,每次开始都从sum中减去到根结点的值,然后再判断当前的节点作为根结点到其左孩子和右孩子的距离与t的关系。

性能分析:

大神的写法就是厉害,这个故事告诉我们递归调用性能真的很优,下次直觉想到循环调用的时候,可以考虑一下递归调用

(二)113题

题目地址:https://leetcode-cn.com/problems/path-sum-ii/description/

题目描述:给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

解决方案:

class Solution {
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        vector<vector<int>> res;
        vector<int> out;
        worker(root,sum,out,res);
        return res;  
    }
    //递归调用,实现对节点的路径总和判断和路径记录功能
    void worker(TreeNode* node,int sum,vector<int>& out,vector<vector<int>>& res){
        if(!node) return;
        out.push_back(node->val);
        if(sum==node->val && !node->left && !node->right)
        {
            res.push_back(out);
        }
        worker(node->left,sum-node->val,out,res);
        worker(node->right,sum-node->val,out,res);
        out.pop_back();
    }
        
};


备注:同样使用递归调用,但由于代码较长,多写了一个函数,函数实现对二叉树中不同节点的处理进行记录。其中res为满足要求或者等待判断的当前路径,out是在新加入的路径不符合要求时,退出的节点。

性能分析:

说明:这个故事告诉我们遇到不会的问题,参考学习大神的代码没有问题,哪怕学习思路涨涨见识也好

(三)437题

题目地址:https://leetcode-cn.com/problems/path-sum-iii/description/
题目描述:

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

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

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

解决方案:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int pathSum(TreeNode* root, int sum) {
        int cnt = 0;
        dfs1(root, sum, cnt);
        return cnt;
        }
    //dfs用来计算二叉树中符合要求的路径的长度
    void dfs(TreeNode* root, int sum, int& cnt){
         if(root == NULL) return;
        //累计符合要求的路径个数
       if(root->val == sum) cnt++;
        dfs(root->left, sum-root->val, cnt);
        dfs(root->right, sum-root->val, cnt);
     }
    //用来遍历每个节点
    void dfs1(TreeNode* root, int sum, int& cnt){
         if(root == NULL) return;
        dfs(root, sum, cnt);
        dfs1(root->left, sum, cnt);
        dfs1(root->right, sum, cnt);
    }

};

分析:较II题多了一个遍历二叉树节点的函数

性能分析:


分析:看了三篇大神写的代码,发现实现相同功能的不同写法,其实可以相互借鉴一下


  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值