力扣刷题记录: 1339. 分裂二叉树的最大乘积

        本题是第174场周赛的 Q3,LC竞赛分为1675.

方法一. 递归(超时)

        单纯使用递归对每一个节点进行遍历,代码如下:

class Solution {
    long long ans = -1;
public:
    int maxProduct(TreeNode* root) {
        long long total_sum = sum(root);

        dfs(root,total_sum);

        return ans%(int)(1e9+7);
    }

    long long sum(TreeNode* root){
        if(root == NULL) return 0;

        return root->val+sum(root->left)+sum(root->right);
    }

    void dfs(TreeNode* root,long long total_sum){
        if(!root) return;

        long long a1 = sum(root);
        long long a2 = total_sum-a1;
        ans = max(a1*a2,ans);

        dfs(root->left,total_sum);
        dfs(root->right,total_sum);
    }
};

方法二. 后序遍历+记忆化搜索(时间超过 11.89% cpp用户)

        后序遍历+记忆化搜索可以让父节点直接用到子节点的结果,从而减少递归调用。代码如下:

class Solution {
    long long ans = -1;
public:
    int maxProduct(TreeNode* root) {
        long long total_sum = sum(root);
        map<TreeNode*,long long> record;
        dfs(root,total_sum,record);

        return ans%(int)(1e9+7);
    }

    long long sum(TreeNode* root){
        if(root == NULL) return 0;

        return root->val+sum(root->left)+sum(root->right);
    }

    void dfs(TreeNode* root,long long total_sum,map<TreeNode*,long long>& record ){
        if(!root) return;

        dfs(root->left,total_sum,record);
        dfs(root->right,total_sum,record);
        long long a1,a2;
        if(record.count(root->left)==1){
            a1 = record[root->left];
        }
        else
            a1 = sum(root->left);
        
        if(record.count(root->right)==1){
            a2 = record[root->right];
        }
        else
            a2 = sum(root->right);
        
        long long sum_tmp = a1 + a2 + root->val;
        record[root] = sum_tmp;
        ans = max(ans,sum_tmp*(total_sum-sum_tmp));
        return;
    }
};

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值