【LeetCode热题100】437. 路径总和 III(二叉树)

一.题目要求

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二.题目难度

中等

三.输入样例

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

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

提示:
二叉树的节点个数的范围是 [0,1000]
− 1 0 9 < = N o d e . v a l < = 1 0 9 -10^9 <= Node.val <= 10^9 109<=Node.val<=109
− 1000 < = t a r g e t S u m < = 1000 -1000 <= targetSum <= 1000 1000<=targetSum<=1000

四.解题思路

解法1:推了一节课迭代发现不行,还是只能递归,依赖这个公式
每个结点新增路径值 = 左子树所有路径 + 该结点值 + 右子树所有路径 + 该结点值 + 该结点本身的值
解法2:前缀和
GPT的解释
在这里插入图片描述

五.代码实现

解1

class Solution {
public:
    int pathSum(TreeNode* root, int targetSum) {
        mySun(root, targetSum);
        return num;
    }

    vector<long> mySun(TreeNode* root,int targetSum)
    {
        if(root == nullptr) return {};
        vector<long> leftRoad = mySun(root->left, targetSum);
        vector<long> rightRoad = mySun(root->right, targetSum);
        int val = root->val;
        vector<long> result;
        for(auto v : leftRoad) 
            result.push_back(v + val);
        for(auto v : rightRoad) 
            result.push_back(v + val);
        result.push_back(val);
        for(auto v : result) if(v == targetSum) num++;
        return result;       
    }
private:
    int num = 0;
};

GPT解2:

class Solution {
public:
    int pathSum(TreeNode* root, int targetSum) {
        unordered_map<long, int> prefixSumCount;
        prefixSumCount[0] = 1; // 初始条件:和为0的路径有1条(不选择任何节点)
        return dfs(root, 0, targetSum, prefixSumCount);
    }

private:
    int dfs(TreeNode* node, long currentSum, int targetSum, unordered_map<long, int>& prefixSumCount) {
        if (!node) return 0;

        currentSum += node->val; // 更新当前路径和
        int numPathsToCurr = prefixSumCount[currentSum - targetSum]; // 找到以当前节点结束,和为targetSum的路径数量
        prefixSumCount[currentSum]++; // 更新路径和出现的次数

        // 递归遍历左右子树
        int totalPaths = numPathsToCurr 
                        + dfs(node->left, currentSum, targetSum, prefixSumCount) 
                        + dfs(node->right, currentSum, targetSum, prefixSumCount);

        prefixSumCount[currentSum]--; // 回溯:恢复当前路径和出现的次数,为其他路径的遍历保持正确的计数

        return totalPaths;
    }
};

六.题目总结

适当用回溯+前缀和解决重复计算

相关推荐

  1. leetcode展开为链表

    2024-03-28 09:30:07       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-28 09:30:07       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-28 09:30:07       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-28 09:30:07       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-28 09:30:07       18 阅读

热门阅读

  1. Linux | CLI arguments 和 Environment variables 是什么

    2024-03-28 09:30:07       20 阅读
  2. Cocoapods版本更新与切换

    2024-03-28 09:30:07       20 阅读
  3. C语言 数组声明

    2024-03-28 09:30:07       15 阅读
  4. Problem reading font data问题(Docker版)

    2024-03-28 09:30:07       21 阅读
  5. P1025 [NOIP2001 提高组] 数的划分

    2024-03-28 09:30:07       18 阅读
  6. 腾讯云CVM S5云服务器4核8G多少钱一年?

    2024-03-28 09:30:07       20 阅读
  7. 【有芯职说】数字IC前端工程师

    2024-03-28 09:30:07       19 阅读