Leetcode 剑指 Offer II 050. 路径总和 III

题目难度: 中等

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

给定一个二叉树的根节点 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]
  • -10^9 <= Node.val <= 10^9
  • -1000 <= targetSum <= 1000

题目思考

  1. 如何快速计算任意路径的和?
  2. 如何快速得到指定和的路径数目?

解决方案

思路
  • 要想得到任意从上到下的路径的和, 很容易想到类似数组前缀和的做法
    • 例如对于上述示例, 要想得到最右侧 4->1 的路径和, 我们可以通过计算根节点到节点 1 和节点 8 的前缀和差值来得到: sum(5->8->4->1) - sum(5->8)
  • 通过这样预处理, 我们可以得到任意从上到下路径的和, 那如何快速得到指定和的路径数目呢?
    • 我们可以额外引入一个计数字典 sumCnt, 来统计当前路径已经遍历过的所有节点的前缀和的计数, 注意初始化sumCnt[0] = 1, 代表路径没有任何节点的情况
    • 在遍历当前节点时, 假设其前缀和为 curSum, 目标路径和为 targetSum, 那么以当前节点为终点的所有路径中, 路径和为 targetSum 的路径数目即为 sumCnt[curSum - targetSum], 累加所有节点的这一数目, 就得到了最终结果
  • 下面代码中有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(N): 每个节点只会被遍历一次
  • 空间复杂度 O(logN): 递归调用最多使用 O(logN) 栈空间, 而前缀和计数字典也会存当前路径上的节点, 这部分也是 O(logN)
代码
class Solution:def pathSum(self, root: TreeNode, targetSum: int) -> int:# 递归+前缀和计数字典# sumCnt是前缀和计数字典{curSum:cnt}, 统计当前路径上前缀和是curSum的路径数目cntsumCnt = collections.defaultdict(int)# 显然刚开始时就存在前缀和是0的一种情况, 即空路径sumCnt[0] = 1# res记录最终满足条件的路径数目res = 0def dfs(node, curSum):nonlocal resif not node:# 当前节点为空, 返回return# 更新当前前缀和curSum += node.val# 以当前节点为终点的满足条件的路径数目为sumCnt[curSum - targetSum], 累加到最终结果中res += sumCnt[curSum - targetSum]# 当前前缀和计数+1, 在遍历子树中可以被用到sumCnt[curSum] += 1# 继续递归左右子树dfs(node.left, curSum)dfs(node.right, curSum)# 最后恢复现场, 因为退出当前递归函数后, 当前节点就不在路径上了, 所以其计数要-1sumCnt[curSum] -= 1dfs(root, 0)return res

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InstructionGPT

之前是写在[Instruction-tuning&#xff08;指令微调&#xff09;]里的&#xff0c;抽出来单独讲一下。 基本原理 在做下游的任务时&#xff0c;我们发现GPT-3有很强大的能力&#xff0c;但是只要人类说的话不属于GPT-3的范式&#xff0c;他几乎无法理解。例如&#xff0c;我们…

轻量级仿 SpringBoot=嵌入式 Tomcat+SpringMVC

啥&#xff1f;Spring Boot 不用&#xff1f;——对。就只是使用 Spring MVC Embedded Tomcat&#xff0c;而不用 Boot。为啥&#xff1f;——因为 Boot 太重了&#xff1a;&#xff09; 这是反智吗&#xff1f;Spring Boot 好好的就只是因为太重就不用&#xff1f;——请允许…

大模型如何商业变现?小i机器人发布华藏大模型生态

华藏通用大模型生态体系由“113”三部分组分&#xff0c;即&#xff1a;一个能力基座一项产品支撑三项服务保障。 今年以来&#xff0c;市场上各类人工智能大模型如雨后春笋&#xff0c;但如何将大模型进行科学的商业变现&#xff0c;成为摆在行业面前的一道难题。在刚刚召开的…

RabbitMQ基础

目录 RabbitMQ的可靠性投递 确保消息正确地发送至 RabbitMQ 确保消息接收方消费了消息 流程分析 1.生产者发送消息给Broker 2.交换机路由消息到队列 3.消息存储在队列 4.消费者订阅并消费消息 三个重要概念 RabbitMQ集群模式 RabbitMQ的可靠性投递 在 RabbitMQ 中&a…

使用el-tree问题之清空勾数据不生效

一、问题场景描述 在做角色菜单按钮权限时&#xff0c;多数采用树结构勾选数据&#xff0c;这里使用了element中的el-tree。如下图&#xff1a; 1、我给角色1勾选了权限列表数据的前三行&#xff0c; 点击弹框的确定 2、紧接着点击角色2的权限按钮&#xff0c;给角色2分配修…

hdlbits系列verilog解答(32位加法器)-25

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 您将获得一个执行 16 位加法的模块 add16 。实例化其中两个以创建一个 32 位加法器。一个 add16 模块在接收到第一个加法器的进位结果后&#xff0c;计算加法结果的低 16 位&#xff0c;而第二个 add16 模块计…

亚马逊哪个站点好做?亚马逊全球站点介绍!

前言 亚马逊全球有18个站点&#xff0c;其中七大站点分别为&#xff1a;北美站、欧洲站、日本站、澳洲站、印度站、中东站、新加坡站。按照国家和地区分为中国、美国、加拿大、墨西哥、英国、德国、法国、西班牙、意大利、澳大利亚、日本、印度、土耳其、中东和巴西。不同的站…

Mac-postman存储文件目录

今天postman弹窗要求登录账号才可访问之前的API文档数据。 但是这postman的账号又是前同事的账号&#xff0c;我没有他的账号和密码啊。 登录了我自己的postman账号后&#xff0c;所有的api文档都不见了....我服了。 首先去屏幕左上角---> 前往 --->个人 然后键盘按显…

JavaScrip的DOM接口

JavaScript的DOM&#xff08;Document Object Model&#xff09;是一种接口&#xff0c;它允许程序和脚本动态地访问和更新文档的内容、结构和样式。DOM是一种将HTML或XML文档表示为对象树的标准方式。 在JavaScript中&#xff0c;DOM提供了一种方式来操作HTML或XML文档的元素…

微服务-统一网关Gateway

网关的作用 对用户请求做身份认证、权限校验将用户请求路由到微服务&#xff0c;并实现负载均衡对用户请求做限流 搭建网关服务 创建新module&#xff0c;命名为Gateway&#xff0c;引入依赖&#xff08;1.SpringCloudGateway依赖&#xff1b;2.Eureka客户端依赖或者nacos的服…

第二证券:监管效能不断提升 并购重组步入“全面注册制时代”

跟着本年2月全面注册制革新相关原则的正式发布&#xff0c;上市公司并购重组亦全面步入“注册制时代”。本钱商场根底性原则的适应性、包容性明显前进&#xff0c;为推进上市公司做强主业、前进质量提供助力&#xff0c;也让并购重组商场的“老旋律”在全面注册制的布景下弹出“…

27 行为型模式-解释器模式

1 解释器模式介绍 //用于两个整数相加的方法 public static int add(int a , int b){ return a b; } //用于三个整数相加的方法 public static int add(int a , int b,int c){ return a b c; } public static int add(Integer ... arr){ int sum 0; for(Integer num : arr)…