在二叉树中找到累加和为指定值的最长路径(前缀和)

给定一颗二叉树和一个整数 sum,求累加和为 sum 的最长路径长度。路径是指从某个节点往下,每次最多选择一个孩子节点或者不选所形成的节点链

求和为指定值的最长路径,我们可以把每一条路径看作一个数组,然后对他进行求指定值,使用前缀和的方法可以很好的实现,也可以使用正常的遍历,对每一个结点进行计算

前缀和

public static int pathSum(TreeNode root, int targetSum) {
        // key为路径和,value为路径和最早出现的层数
        Map map = new HashMap();
        map.put(0, 0);
        return preOrder(root,targetSum,map,0,1,0);
    }
    public static int preOrder(TreeNode root,int targetSum,
            Map map,int preSum,int level,int maxLen){
        if(root == null) {
            return maxLen;
        }
        // 计算从根节点到当前结点的路径和
        preSum += root.value;
        // 这里需要提前将当前节点对应的层数加入哈希表中,因为有可能我们当前节点对应的前缀和就是presum-targetSum
        if(!map.containsKey(preSum)) {
            // 如果哈希表中没有preSum,则将当前preSum和其第一次出现的位置加入哈希表中
            map.put(preSum, level);
        }
        if(map.containsKey(preSum - targetSum)) {
            // 计算最大长度
            maxLen = Math.max(level - map.get(preSum - targetSum), maxLen);
        }

        // 计算当前结点的左右节点
        maxLen = preOrder(root.left,targetSum,map,preSum,level + 1,maxLen);
        maxLen = preOrder(root.right,targetSum,map,preSum,level + 1,maxLen);
        /*
         * 这一步的操作是为了清除map表中的当前结点的数据,因为当前节点的子树已经处理完了,要返回其父节点,对父节点的子树进行处理,
         * 如果当前节点的数据还在map里面,后面在其他子树中可能会有一样的数据key和value,简单地说就是为了处理一段路径的时候,不会被
         * 其他路径上的数据影响
         * */
        if(map.get(preSum) == level) {
            map.remove(preSum);
        }
        return maxLen;
    }

代码解析:

这个思路可以理解为将每一个结点到叶子节点的路径当作数组来求最大子数组长度

使用前缀和加哈希表优化,我们遍历树路径的时候,计算根节点到当前节点的前缀和,我们将前缀和作为key,当前前缀和当前节点位置作为value存入哈希表中,当我们每一次遍历数组元素的时候,判断presum-k在哈希表中有没有对应的数据,如果有,从当前位置到哈希表中对应的位置之间的差值就是对应的路径的长度( 通过sum-k可以得到子数组的长度是因为,我们计算k的时候是使用preSum[i]-preSum[j] = k,那么preSum[j] = preSum[i]-k,所以当哈希表中存在sum-k就表示当前前缀和数组中存在子数组和为k),遍历完数组后得到的最大长度就是最大子路径长度

注意:我们将每一个结点到叶子节点的路径当作数组进行处理,但是当我们从一条路径跳出来去其他路径计算的时候,原来路径的数据会对现在的路径计算进行影响,所以每次退出当前路径(其实也就是当前节点到了叶子节点)的时候需要将当前节点的数据从哈希表中删除

看见连续累加和为指定值就要想到使用前缀和。

Original: https://www.cnblogs.com/foldn/p/15969876.html
Author: foldn
Title: 在二叉树中找到累加和为指定值的最长路径(前缀和)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579746/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring系列14:IoC容器的扩展点

    Spring系列14:IoC容器的扩展点 回顾 知识需要成体系地学习,本系列文章前后有关联,建议按照顺序阅读。上一篇我们详细介绍了Spring Bean的生命周期和丰富的扩展点,没…

    Java 2023年6月5日
    0101
  • Cron表达式(七子表达式)

    秒 分 时 日 月 周 年 可用的值 0~59 0~59 0~23 1~31 1~12(JAN-DEC) 1~7(SUN-SAT) 1970~2099 可用的通配符 , &#821…

    Java 2023年6月8日
    068
  • 西门子PLC数据读取 Observer设计模式

    当我听到这个需求的时候,我差点爆粗口(实际上可能已经爆了,不过我忘了)。 需求刚开始是: C#连接PLC Modbus读取值。 我用C#写完了,觉得太简单了,还弄了个窗体。 接着是…

    Java 2023年6月9日
    077
  • Swagger框架

    开发软件:IDEA 项目类型:SpringBoot的JavaWeb 官网:https://swagger.io/ 在线文档:https://swagger.io/docs/spec…

    Java 2023年6月9日
    091
  • Redis锁相关

    Redis锁相关 君不见,高堂明镜悲白发,朝如青丝暮成雪。 背景:面试的时候被问到有哪些锁,很快脱口而出Volatile、Synchronized和ReentrantLock,也能…

    Java 2023年6月5日
    079
  • react nginx配置

    server { listen 8080; # server_name your.domain.com; root /home/root/react-demo/dist; inde…

    Java 2023年5月30日
    080
  • MySql数据库备份与还原

    备份(mysqldump) 实现功能: 1、备份指定的数据库 2、删除指定天数前的备份文件,默认设定了1天 脚本示例(mysql_bak.sh) 数&…

    Java 2023年6月8日
    087
  • 五月,你好啊!

    五月,你好啊! 当我连续出现在深夜,就代表… 最近要学得东西变多了许多,今天是五四青年节,吾辈青年,请继续前进于中国强国道路上,不断努力奋斗,学习专业知识与个人技能专长…

    Java 2023年6月5日
    073
  • [转]Nginx主动式后端服务器健康检查配置

    环境: SpringCloud微服务(eureka注册中心);nginx作为负载均衡; 场景: Nginx -> A服务当流量高峰期时,kill A服务A服务还没有挂掉,但是…

    Java 2023年5月30日
    060
  • leetcode 572. Subtree of Another Tree 另一棵树的子树 (简单)

    一、题目大意 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 fa…

    Java 2023年6月14日
    089
  • Seleium Grid配置中的MaxInstances和MaxSession详解

    MaxInstances This says….how many instances of same version of browser can run over t…

    Java 2023年5月30日
    079
  • 记录一下Junit测试MongoDB,获取MongoTemplate

    只是自己记录一下,测试MongoDB帮助类时,没有配置文件的测试 public class HelperTest { MongoTemplate template; @Before…

    Java 2023年6月8日
    079
  • JeeSite 快速开发平台、架构特点、安全方面、为什么好、优势

    1、架构特点 以 Spring Boot 2 为基础,Maven 多项目依赖,模块分项目,松耦合,方便模块升级、增减模块 模块化的数据库自动升级程序,当模块升级代码需要更新数据库时…

    Java 2023年6月7日
    094
  • Nginx 源码分析– 浅谈对模块module 的基本认知

    分析nginx源码,谈到模块module是必然的。纵观nginx源码,可以说模块module机制是整个nginx的骨架。因此,对nginx的源码进行分析,那么对模块module就需…

    Java 2023年6月15日
    072
  • Redis客户端连接远程Redis服务器失败解决百分百

    redis远程连接服务器失败,查看网上把 bind 127.0.0.1改了, protected-mode保护模式也关闭了, daemonize yes进程守护模式也关闭了但是还是…

    Java 2023年6月5日
    067
  • HashMap源码个人理解

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球