树形动态规划DP

一般而言,大多数动态规划dp是基于数组结构的,其实,在树状结构中也能实现dp,下面就两道算法题给出例子

1:二叉树最长路径

题目描述:https://leetcode.com/problems/sum-of-subarray-minimums/
思路:二叉树最长路径来源于以下三者之中的最大——左子树、右子树、左子树深度+右子树深度
容易写出以下递归的解法:

public static int diameterOfBinaryTree(TreeNode root) {
        if (root == null) return 0;
        if(root.left == null && root.right == null) return 1;
        int a = depth(root.left) + depth(root.right), b =   diameterOfBinaryTree(root.left), c = diameterOfBinaryTree(root.right);
        return Math.max(a,
                Math.max(b, c)
                );
    }

    private static int depth(TreeNode root) {
        if (root == null) return 0;
        return 1 + Math.max(depth(root.left), depth(root.right));
    }

提交上去后,发现只击败了10%的java提交,不难发现,这里递归的子问题是:每棵子树的深度和最长路径, 对于这些子问题,我们进行了重复计算。现在可以思考:如何对于一个子问题,只进行一次计算?
对于每棵子树,他的深度与内部最长路径可以看作是一个属性,用一个int数组(内含两个属性:深度与内部最长路径)来存储,并不断向上(自己的根节点)返回
基于这个思路,我们写出了下面的代码

 //  树型dp
    public static int diameterOfBinaryTree1(TreeNode root) {
        return process(root)[0];
    }

    // int[2] = [best, height]
    private static int[] process(TreeNode node) {
        if (node == null) return new int[]{0, 0};
        int[] left = process(node.left);
        int[] right = process(node.right);
        int[] info = new int[2];
        int maxOfLeftAndRight = Math.max(left[0], right[0]);
        info[0] = Math.max(maxOfLeftAndRight, left[1] + right[1]);
        info[1] = 1 + Math.max(left[1], right[1]);
        return info;
    }

击败了100%的java提交

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值