[力扣每日习题][1339]. 分裂二叉树的最大乘积 2026.01.07

**难度评级:**中等

题目:

给你一棵二叉树,它的根为 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)

解题思路:DFS

可以先计算得到所有节点的和 ,再通过数组存储所有子树的和 ,遍历数组的时候,计算:子树和 × (所有节点和 - 子树和),也就是分割成两个子树的乘积,找出最大的那一个乘积即可。

深度优先搜索就是沿着一条路走到底,走不通了再回到上一层继续走。可以采用递归的方式实现,将根节点作为起始节点放入函数当中,函数需要完成如下操作:

① 定义 left 、 right、temp 3个参数,每次调用 DFS 函数的时候都需要重置为 0 ;

② 判断是否有左孩子,有就调用 DFS 函数,并且将函数的返回值存入 left 中,没有就下一步;

③ 判断是否有右孩子,有就调用 DFS 函数,并且将函数的返回值存入 right 中,没有就下一步;

④ 计算 temp = left + right + 当前节点的值;

⑤ 将 temp 存入子树和的数组中。

⑥ 返回 temp(当前子树的和);


解析:根节点调用 DFS 函数的时候,会一直嵌套直到找到二叉树**最左边的那个叶子节点,**接下来,由于 left 和 right 为 0,那么 temp = 0 + 0 + 当前节点的值,将 temp 返回至上一层,也就是当前节点的父亲节点,父亲节点已经完成了 ② ,在这一层 left 的值是刚才计算得到的 temp,接下来进行 ③ ,如果没有右孩子那么 right = 0,在这一层的 temp = left + 0 + 当前节点的值,结束这层循环,再返回上一层。

理解 DFS 的关键就是,先找到一条路一直到底,然后再慢慢往回退

接下来我们用一颗二叉树来模拟一下这个 DFS 的流程。


以如下二叉树为例,依次分析每个节点,下面是根节点的初始状态,将各个参数重置为 0,temp是当前节点孩子子树的和+当前节点值;注意这里的left 和 right 分别指的左孩子子树的和、右孩子子树的和,不是左孩子和右孩子的值,在代码中为 left = DFS(2);right = DFS(3);是递归调用函数后返回的值。


对于 1 这个节点,它有左孩子,那么这里需要递归调用 DFS 函数,将 2 这个节点作为根节点进行分析,对应着步骤 ②,2 这个节点进入后,它需要开始循环它的 DFS 函数。


节点 2 有左孩子 4,那么将节点 4 作为根节点进行分析,调用 DFS 函数。


此时节点 4 ,进行步骤 ②、③,由于它没有孩子,那么只能进行步骤 ④,计算 temp,最后将计算结果保存。


第三层 4 进行步骤 ⑥,返回上一层,将计算结果返回给上一层对应调用 DFS(4)的那个参数,上一层调用 DFS(4)的是第二层 2 在步骤 ② 的时候将左孩子进行递归调用 DFS,那么值就返回给第二层 2 的参数 left


第二层 2 的步骤 ② 结束,现在进行步骤 ③ ,它有右孩子,那么将节点 5 调用 DFS 函数,作为根节点进行分析。


节点 5,没有左右孩子,直接进行步骤 ④。


进行步骤 ⑥,将值返回给上一层的 right。


现在第三层 5 结束,第二层 2 进行步骤 ④,计算它自己的 temp。


第二层 2 ,进行步骤 ⑥,将值返回给上一层的 left。


第二层 2 结束,现在对一层 1 进行步骤 ③,它有右孩子,将右孩子递归调用 DFS


节点 3 ,它没有左孩子,只有右孩子,那么它直接进行步骤 ③。


第三层 6 ,没有孩子,是叶子节点,直接步骤 ④,计算 temp。


进行步骤 ⑥,返回上一层,将值给上一层的 right。


第二层 3 进行步骤 ④。


进行步骤 ⑥,返回上一层,将值返回给上一层的 right。


第一层 1 进行步骤 ④。


最后进行步骤 ⑥,将最后的值返回即可,在递归调用的时候,所有的子树和都已计算并保存至一个数组,接下来只需要遍历数组,计算 每棵子树和 * (总和 - 该子树和) 找到最大值就可以了。


题解代码如下:

复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    const int MOD = 1e9 + 7;
    long long dfs(TreeNode* root, vector<long long>& list){
        long long l = 0;
        long long r = 0;
        long long temp = 0;
        if (root -> left != nullptr){
            l = dfs(root -> left, list);
        }
        if (root -> right != nullptr){
            r = dfs(root -> right, list);
        }
        temp = l + r + root -> val;
        list.push_back(temp);
        return temp;
    }

    int maxProduct(TreeNode* root) {
        vector <long long> list;    // 用于存储所有子树和
        long long sum = dfs(root, list);
        long long res = 0;
        for (auto i:list){
            long long cal = i * (sum - i);
            if (cal > res){
                res = cal;
            }
        }
        return res % MOD;
    }
};

**优化思路:**暂无。

相关推荐
dazzle14 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵14 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强14 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发14 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
张登杰踩14 小时前
MCR ALS 多元曲线分辨算法详解
算法
YuTaoShao14 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法一)排序+滑动窗口
算法·leetcode·排序算法
波波00715 小时前
每日一题:.NET 的 GC是如何分代工作的?
算法·.net·gc
HY小宝F15 小时前
职场沟通的深层智慧:从对抗到协作的自我修炼
职场和发展
风暴之零15 小时前
变点检测算法PELT
算法
深鱼~15 小时前
视觉算法性能翻倍:ops-cv经典算子的昇腾适配指南
算法·cann