1339. 分裂二叉树的最大乘积

Hi 大家好,我是张小猪。欢迎来到『宝宝也能看懂』系列之 leetcode 周赛题解。

这里是第 174 期的第 3 题,也是题目列表中的第 1339 题 -- 『分裂二叉树的最大乘积』

题目描述

给你一棵二叉树,它的根为 root。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。

由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。

示例 1:

输入:root = [1,2,3,4,5,6]
输出:110
解释:删除红色的边,得到 2 棵子树,和分别为 11 和 10 。它们的乘积是 110 (11*10)

示例 2:

输入:root = [1,null,2,3,4,null,null,5,6]
输出:90
解释:移除红色的边,得到 2 棵子树,和分别是 15 和 6 。它们的乘积为 90 (15*6)

示例 3:

输入:root = [2,3,9,10,7,8,6,5,4,11,1]
输出:1025

示例 4:

输入:root = [1,1]
输出:1

提示:

  • 每棵树最多有 50000 个节点,且至少有 2 个节点。

  • 每个节点的值在 [1, 10000] 之间。

官方难度

MEDIUM

解决思路

题目提供了一棵二叉树的根节点,需要我们删除一条边使得这棵二叉树变成两棵二叉树。而要求就是对这两棵二叉树里各个节点分别求和之后,这两个和的乘积最小。

不知道小伙伴们是什么想法,不过小猪看完题目之后第一反应是,先遍历起来。毕竟,只对着一个根节点的话,再好的戏也出不来。而提到遍历二叉树的话,又想少写一点代码,那小猪的第一反应就是用递归来实现深度优先遍历啦。

接下来回到题目的需求上,我们需要找到拆分后两个和的乘积最大。由于这棵树给定后就不会变了,所以所有节点求和的值其实是一定的。而对于这个确定的值,我们把它拆成两个加数后要使得它们的乘积最大,那么这两个数应该尽可能的靠近总和的二分之一。相信到这里,很多小伙伴都是能想到哒。不过再往后,如果直接用数学的方式来处理这个问题,小猪就想不明白了。小猪苯苯的,希望小伙们能帮帮我。

那没有了数学的方法,小猪就只能用计算机的方法啦。我们可以想象一下,在去掉一条边之后,拆分成的两棵二叉树,其中必然有一棵的顶点位于我们刚才断掉的那条边的下游。也就是说,从当前位置拆开之后,其实分成的两部分,就是以当前节点为顶点的二叉树,以及其他的节点。

想通了这一点之后,再结合前面提到的总和是固定不变的。那么我们的思路也就大概清晰啦。

直接方案

我们可以先计算出所有节点的总和。然后对于每一个节点,我们也能算出以它为顶点的子二叉树的总和。那么剩下的那一部分也就知道啦。在对每个可能的节点都进行这样的计算之后,我们就能找到那个最大的乘积了。

基于这个思路,我们具体的流程如下:

  1. 遍历二叉树,得到所有节点值的总和。

  2. 遍历二叉树,针对每一个可能的节点,假设从这里拆分,然后计算可能的乘积,并记录最大值。

  3. 返回最大的乘积。

基于这个流程,我们可以实现类似下面的代码:

const maxProduct = root => {let sum = max = 0;sum = helper(root);helper(root);return max % (10 ** 9 + 7);function helper(node) {const subSum = node.val + (node.left ? helper(node.left) : 0) + (node.right ? helper(node.right) : 0);sum && subSum * (sum - subSum) > max && (max = subSum * (sum - subSum));return subSum;}
};

优化

上面的代码我们对整个二叉树进行了两次遍历,其中第一次是为了计算总和,而第二次则是进行每个节点的子二叉树的计算和判断。

不知道小伙伴们有没有发现,其实我们第二次遍历中所计算的东西,在第一次遍历的时候也是可以得到的。而唯一最初无法计算的,就是与总和的差值做乘积的结果。那么我们其实可以把前面的内容都记录下来,在得到了总和之后直接进行计算即可。

基于这个优化思路,我们具体的流程如下:

  1. 遍历二叉树,得到所有节点值的总和,并记录以每个节点为首的子二叉树的总和。

  2. 尝试这些子二叉树的和,并计算出最大的乘积。

基于这个流程,我们可以实现类似下面的代码:

const maxProduct = root => {const subSums = new Uint32Array(50000);let max = idx = 0;const sum = helper(root);for (let i = 0; i < idx; ++i) {const val = subSums[i];val * (sum - val) > max && (max = val * (sum - val));}return max % (10 ** 9 + 7);function helper(node) {const subSum = node.val + (node.left ? helper(node.left) : 0) + (node.right ? helper(node.right) : 0);subSums[idx++] = subSum;return subSum;}
};

总结

这道题的逻辑并不复杂,还是非常套路的内容。关键点就是在与要相通我们拆分后的情况究竟是什么,也就是分析中提到的拆分之后其中一部分必然是以当前节点为首的子二叉树。而剩下的就是套用深度优先遍历去实现即可。

在我们这么多期的周赛题解之后,相信小伙伴们已经逐渐的开始熟悉这些套路了吧。突然觉得小猪做的事情还是有意义的呢,开心的摇了摇猪尾巴 >.<

1、写给大忙人看的进程和线程

2、一个HTTP数据包的奇幻之旅

3、一个函数解决【LeetCode 买卖股票的最佳时机】系列所有题目!

4、原来状态机也可以用来刷LeetCode?

5、【算法提高班】《我的日程安排表》系列

6、用好这几个工具,能大幅提升你的 Git/GitHub 操作效率!

如果觉得文章不错,帮忙点个在看呗

宝宝也能看懂的 leetcode 周赛 - 174 - 3相关推荐

  1. 宝宝都能看懂的机器学习世界

    点击上方↑↑↑蓝字关注我们~ 「2019 Python开发者日」,购票请扫码咨询 ↑↑↑ 作者 | 武博士.宋知达.袁雪瑶.聂文韬 来源 | 大鱼AI(ID:DayuAI-Founder) 人类需要经 ...

  2. 第一次LeetCode周赛心得(力扣-cn周赛,使用python3)

    第一次力扣参赛:第 174 场力扣周赛 第 174 场力扣周赛赛题: https://leetcode-cn.com/circle/discuss/lEfEkb/view/OrAJAh/ 第 174 ...

  3. 春节充电 | 文科生都能看懂的机器学习教程:梯度下降、线性回归、逻辑回归(附动图解释)...

    来源:新智元 本文约4200字,建议阅读10+分钟. 本文浅显易懂的方式讲解机器学习,力求让没有理科背景的读者都能看懂. [ 导读 ]虽然在Coursera.MIT.UC伯克利上有很多机器学习的课程, ...

  4. 文科生都能看懂的机器学习教程:梯度下降、线性回归、逻辑回归

    来源:新智元 本文约4200字,建议阅读10+分钟. 本文浅显易懂的方式讲解机器学习,力求让没有理科背景的读者都能看懂. [ 导读 ]虽然在Coursera.MIT.UC伯克利上有很多机器学习的课程, ...

  5. 成员缩写_「gnps,nbcs」是什么意思?00后饭圈缩写你看懂多少

    在职读免联考MBA 做新一代管理者! 2019年00后已开始步入成年 逐渐成为社会的焦点 要想了解00后 就必须解锁他们的语言"密码" 创造了一套他们独有的语系, 就像摩斯密码,生 ...

  6. 语言线性拟合线对称_文科生都能看懂的机器学习教程:梯度下降、线性回归、逻辑回归...

    [新智元导读]虽然在Coursera.MIT.UC伯克利上有很多机器学习的课程,包括吴恩达等专家课程已非常经典,但都是面向有一定理科背景的专业人士.本文试图将机器学习这本深奥的课程,以更加浅显易懂的方 ...

  7. [LeetCode周赛复盘] 第 314 场周赛20221009

    [LeetCode周赛复盘] 第 314 场周赛20221009 一.本周周赛总结 二. [Easy] 6201. 找出前缀异或的原始数组 1. 题目描述 2. 思路分析 3. 代码实现 三.[Eas ...

  8. leetcode周赛5465. 子树中标签相同的节点数

    leetcode周赛5465. 子树中标签相同的节点数 给你一棵树(即,一个连通的无环无向图),这棵树由编号从 0 到 n - 1 的 n 个节点组成,且恰好有 n - 1 条 edges .树的根节 ...

  9. [LeetCode周赛复盘] 第 324 场周赛20221218

    [LeetCode周赛复盘] 第 324 场周赛20221218 一.本周周赛总结 二. [Easy] 6265. 统计相似字符串对的数目 1. 题目描述 2. 思路分析 3. 代码实现 三.[Med ...

最新文章

  1. docker nodejs 基本应用
  2. 用JS实现一个定时间段的跳转
  3. WordPress ProPlayer插件‘id’参数SQL注入漏洞
  4. Scala基础教程(六):字符串、数组、集合
  5. NYOJ 630 Problem of IP
  6. ResNet网络详解与keras实现
  7. 学生渐进片add如何给_渐进片的那些事「5」——验配之前的问诊
  8. Java如何进行Base64的编码(Encode)与解码(Decode)
  9. exposed beyond app through Intent.getData()
  10. 使用Python的VAR模型
  11. 读书笔记:程序员的工具箱之“代码片段”
  12. 豆瓣读书isbn 查询
  13. 【剧透】2017云栖大会•北京峰会——企业云上业务优化专场
  14. 【docker】win10系统下docker容器安装及使用(二):docker通过commit及dockerfile进行创建
  15. thymeleaf中三元运算符嵌套写法
  16. DFINITY 明星项目盘点,区块链热门赛道一览
  17. Gitblit团队协作
  18. 800万商户都在抖音开通了企业号建立了私域流量新领地,你还在等什么
  19. Fluent仿真计算前的准备
  20. 需要把哥德尔不完备定理讲到什么程度才能被大众所熟知?

热门文章

  1. 微信小程序转钉钉小程序适配问题
  2. 车内看车头正不正技巧_驾考科目二自动挡学车攻略小技巧。
  3. java算法之———河内之塔
  4. 材料硕士转行计算机经验分享(Java开发)
  5. HTML5网页设计样式-CSS设置文字样式
  6. C语言基本数据类型笔记整理(整型、实型/浮点型、字符型、枚举型、构造类型、指针类型、空类型)
  7. 5款windows神器吐血推荐!个个都是精品
  8. 太燃了!战绩破百!新标家居火爆建博会,滿誉而归!
  9. 2023年全国最新安全员精选真题及答案49
  10. 2023年全国最新安全员精选真题及答案16