LeetCode437.路径总和III

news2024/11/25 22:48:07

 看完题目我就拿直接用递归写了如下代码:

class Solution {
    private int ans;
    public int pathSum(TreeNode root, int targetSum) {
            ans =0;
            dfs(root, targetSum, 0);
            return ans;
    }
    public void dfs(TreeNode root, int targetSum, int sum){
        if(root == null)return;
        sum += root.val;
        if(sum == targetSum)ans++;
        dfs(root.left, targetSum, sum);
        dfs(root.left, targetSum, 0);
        dfs(root.right, targetSum, sum);
        dfs(root.right, targetSum, 0);
        return;
    }
}

 dfs方法中的参数sum表示从前面某个节点到上一个节点的和,拿这个sum加上当前节点的值如果等于targetSum那么答案数+1,然后可以把现在的sum往下面传递,也可以传一个0下去表示从下一个节点开始计算和,然后示例过了,测试用例没过,因为这样的话重复计算了多个答案,比如一个全右的树1,2,3,4,5,target=3,那么在dfs1的时候,传了sum等于0,然后dfs2的时候又传了sum等于0,然后dfs3,这条1,2,3的路径给算进去了,所以这样是不行的。然后自己想了一会没思路就直接看了题解,

题解的第一种做法用的就是深度优先,但和我的不一样,他用了两层递归

首先定义第一个递归方法:

public int rootSum(TreeNode root, int targetSum)

它表示以root为起点的路径中,和为target的个数。在主函数中递归遍历每个节点,把这些节点的rootSum加起来。以下是方法一的代码:

class Solution {
    public int pathSum(TreeNode root, int targetSum) {
            if(root == null)return 0;
            int ans =0;
            ans+=rootSum(root,targetSum);
            ans+= pathSum(root.left, targetSum);
            ans+=pathSum(root.right, targetSum);
            return ans;
    }
    public int rootSum(TreeNode root, long targetSum){
        if(root == null)return 0;
        int ret = 0;
        if(root.val == targetSum) ret++;
        ret+= dfs(root.left, targetSum-root.val);
        ret+= dfs(root.right, targetSum-root.val);
        return ret;
    }
}

在rootSum()方法中要算以root为起点和为targetSum的路径数,就是算以root.left为起点和为targetSum-root.val的路径数加上以root.right为起点,和为targetSum-root.val的路径数。当root.val=targetSum时+1。然后主函数递归遍历每个节点,使得每个节点都调用一遍rootSum()方法。

方法一的时间复杂度时O(n2)很高,做了很多重复的计算。方法二是利用了HashMap里面存放前缀和来减少遍历次数。以下是方法二代码:

class Solution {
    public int pathSum(TreeNode root, int targetSum) {
        Map<Long, Integer> prefix = new HashMap<Long, Integer>();
        prefix.put(0L, 1);
        return dfs(root, prefix, 0, targetSum);
    }

    public int dfs(TreeNode root, Map<Long, Integer> prefix, long curr, int targetSum) {
        if (root == null) {
            return 0;
        }

        int ret = 0;
        curr += root.val;

        ret = prefix.getOrDefault(curr - targetSum, 0);
        prefix.put(curr, prefix.getOrDefault(curr, 0) + 1);
        ret += dfs(root.left, prefix, curr, targetSum);
        ret += dfs(root.right, prefix, curr, targetSum);
        prefix.put(curr, prefix.getOrDefault(curr, 0) - 1);

        return ret;
    }
}

Map<Long, Integer> prefix里面存的是,路径和为key的数量value,long curr表示从根节点到当前节点的和,这一点必须明白。

假如根节点是root,我们正在访问的节点是node,这条路径就是root->p1->p2->..->pk..->node。计算到node的时候从root到node的和是curr,那么我们只要找到前面的一个节点pk,它的curr1是curr-targetNum,那么从pk到node的和就是tagetNum。我们不需要找到这个pk,只需要知道这条路径上有多少个这样的pk就行。所以我们的HashMap中存放的是和为key的数量而不是节点。

理解了这个看dfs方法就比较容易了。

ret = prefix.getOrDefault(curr - targetSum, 0);

这个HashMap的getOrDefault方法是先去get这个key这里是curr-targetSum。如果没有这个key就返回默认值这里是0。这样就拿到了以当前节点为终点和为target的路径的数量,

prefix.put(curr, prefix.getOrDefault(curr, 0) + 1);

然后再把从root到当前节点的和放进map里面,然后递归遍历子节点。因为这个prefix的map是全局都在用的,所以当你把当前节点遍历完了你得回溯,把自己给移出去,因为递归回到前面的时候,前面的节点不能用后面节点的前缀和,所以要把这个前缀和的数量-1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1287530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB】辛几何模态分解分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 辛几何模态分解&#xff08;CEEMDAN&#xff09;是一种处理非线性和非平稳信号的适应性信号分解方法。通过在信号中加入白噪声&#xff0c;并多次进行经验模态分解&#xff08;EMD&#…

CSS BFC特性和应用

目录 1&#xff0c;介绍2&#xff0c;BFC布局规则3&#xff0c;创建BFC4&#xff0c;BFC应用1&#xff0c;浮动子元素使父级高度坍塌2&#xff0c;非浮动元素被浮动元素覆盖3&#xff0c;margin 合并1&#xff0c;父子 margin 合并&#xff1a;父级和第1个/最后1个子元素2&…

【matlab程序】matlab画子图的多种样式

【matlab程序】matlab画子图的多种样式

Ps:文字操作常用快捷键

对文字的设置操作&#xff0c;可在工具选项栏或“字符”面板上进行。但是&#xff0c;如果能记住并使用快捷键&#xff0c;可大大提高工作效率。 设置文字颜色 Color 1、选中几个或全部文字后&#xff0c;除了使用工具选项栏上的“颜色”按钮&#xff0c;还可以使用快捷键 Alt…

【Vue】将官方路由管理器 vue-router 库引入 Vue 项目的三种方法

前言 Vue Router 是 Vue.js 的官方路由管理器。它可以帮助我们在 Vue 应用中实现页面之间的跳转和导航&#xff0c;并且提供了一些高级功能&#xff0c;如路由参数、路由嵌套、路由守卫等。 Vue Router 的主要作用是将不同的组件映射到不同的 URL&#xff0c;并根据 URL 的变化…

UE5 - 把ArchvizExplorer项目改造成自己的数字孪生项目 - 开发记要

参考&#xff1a; https://blog.csdn.net/qq_17523181/article/details/133853099 https://blog.csdn.net/qq_17523181/article/details/134455597 1. 安装项目 https://www.unrealengine.com/marketplace/zh-CN/product/archviz-explorer https://karldetroit.com/archviz-exp…

IDEA中,光标移动快捷键(Shift + 滚轮前后滚动:当前文件的横向滚动轴滚动。)

除此之外&#xff0c;其他常用的光标移动快捷键包括&#xff1a; Shift 滚轮前后滚动&#xff1a;当前文件的横向滚动轴滚动。Shiftenter&#xff1a;快速将鼠标移动到下一行。Ctrl ]&#xff1a;移动光标到当前所在代码的花括号结束位置。Ctrl 左方向键&#xff1a;光标跳转…

华为鸿蒙开发——Stage/FA模型在ArkTs语言、JS语言 实现页面互转

文章目录 一、ArkTs(Stage模型)二、ArkTs(FA模型)三、JS&#xff08;FA模型&#xff09; 一、ArkTs(Stage模型) 目的&#xff1a;实现两个页面的跳转功能 步骤&#xff1a; 1、打开entry > src > main > ets > pages 2、在默认页面基础上&#xff0c;我们添加一个…

线性表之-栈

栈的表示&#xff1a; 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff…

YN 500U无法上网问题

版本信息 YN LU YN上问题现象 在后台ping&#xff0c;在web上抓包 抓包结构发现是收到回包了的 通过ssh登录到网关上抓包&#xff0c;也是一样&#xff0c;是可以抓到回应包的&#xff0c;但是终端上就是无法显示。 通过wan后ping包是能够看到回显的。 这块模组有问题

C++基础 -43- STL库之set集合

在set插入数据的时候会自动排序 set集合定义格式 int myints[] {50,10,40,30,20};set<int,classcomp> second (myints,myints5);设置排序方式 struct classcomp {bool operator() (const int& lhs, const int& rhs) const{return lhs>rhs;} };举例遍历se…

Web APIs—事件监听、事件类型、事件对象、环境对象、回调函数、综合案例:随机点名案例,轮播图完整版,评论区回车发布,Tab栏切换

版本说明 当前版本号[20231205]。 版本修改说明20231205初版 目录 文章目录 版本说明目录Web APIs - 第2天事件事件监听案例&#xff1a;通过点击按钮&#xff0c;弹出一个对话框 事件类型事件处理程序综合案例&#xff1a;随机点名案例 事件类型鼠标事件键盘事件焦点事件案…

为啥你的文案点击量少?快来看看是不是犯了这些误区

信息爆炸的时代下用户注意力成为稀缺资源&#xff0c;一篇文章如果不能在最开始就抓住读者的心就宛如石沉大海&#xff0c;而许多企业在写软文时总会因为点击量太少而焦虑&#xff0c;今天媒介盒子就来和大家分析分析&#xff0c;为啥你的文章点击量少&#xff0c;帮助企业搞清…

vue项目中添加刷新的按钮

刷新功能 点击导航的刷新按钮&#xff0c;刷新下方主体内容&#xff0c;我这边的项目分为左-上-下结构&#xff0c;上边为tabbar组件&#xff0c;下边为main组件&#xff0c;点击刷新整个流程是刷新按钮&#xff0c;去访问它父组件tabbar的兄弟组件main&#xff0c;使main组件…

渗透测试学习day7

文章目录 靶机&#xff1a;VaccineTask1Task2Task3Task4Task5Task6 7-9解题过程Task7Submit user flagSubmit root flag 靶机&#xff1a;Vaccine Task1 问题&#xff1a;除了SSH和HTTP&#xff0c;这个盒子上还托管了什么服务&#xff1f; ftpnmap扫一下 Task2 问题&…

活动目录是什么?

企业在进行数字化转型时&#xff0c;也会面临日益增长的网络用户和复杂的身份管理需求。为了高效地管理用户身份、控制访问权限以及保护企业的数据安全&#xff0c;许多企业选择使用微软的Active Directory&#xff0c;即微软活动目录&#xff0c;来作为网络身份管理系统。 1、…

概率密度函数(PDF)正态分布

概率密度函数&#xff08;PDF&#xff09;是一个描述连续随机变量取特定值的相对可能性的函数。对于正态分布的情况&#xff0c;其PDF有一个特定的形式&#xff0c;这个形式中包括了一个常数乘以一个指数函数&#xff0c;它假设误差项服从均值为0的正态分布&#xff1a; p ( …

算法通关村第十三关-白银挑战数字与数学高频问题

大家好我是苏麟 , 今天带来数字与数学的高频问题 . 加一 描述 : 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个…

D9741 应用于电视摄像机,笔记本电脑等产品中,3.6V ~ 35V 100mA 三极管驱动

D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。 主要特点&#xff1a;● 高精度基准电路 ● 定时闩锁、短路保护电路 ● 低电压输入时误操作保护电路 ● 输出基准电…

时间选择器

<el-form-item label"时间范围"><!-- <el-date-picker size"small"v-model"createTime"type"daterange"range-separator"至"start-placeholder"请输入起始创建时间"end-placeholder"请输入终止创…