首页 > 代码库 > 分治法中使用resultType来让一次递归返回多个结果

分治法中使用resultType来让一次递归返回多个结果

题目:Binary Tree Maximum Path Sum

给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和)。 

 

解法:定义两个函数,maxPathSum(TreeNode root)表示以root为根的树的最大路径长度(即题目所求,至少包含一个节点),rootToAny(TreeNode root)表示从根节点出发的所有路径长度的最大值(至少包含一个节点),则代码如下:

public class Solution {    /**     * @param root: The root of binary tree.     * @return: An integer.     */    public int maxPathSum(TreeNode root) {        // write your code here        if(root==null)            return Integer.MIN_VALUE;                int pathWithoutRoot = Math.max(maxPathSum(root.left),maxPathSum(root.right));        int pathWithRoot = Math.max(rootToAny(root.left),0)+Math.max(rootToAny(root.right),0)+root.val;        return Math.max(pathWithoutRoot,pathWithRoot);            }        public int rootToAny(TreeNode root){        if(root==null)            return Integer.MIN_VALUE;                return Math.max(0,Math.max(rootToAny(root.left),rootToAny(root.right)))+root.val;    }}

 上面代码在lintcode能提交通过,但在leetcode提交则超时。原因是它对每一个节点都递归了两次,一次求解root2Any的结果,一次求解maxPathSum的结果,虽然时间复杂度不变,但相当于时间增加了一倍,leetcode对时间复杂度要求较严格,因此会提示超时,改进的方法就是自己定义一个返回类型,每次递归返回两个值,这样就节约了一半的时间,代码如下:

public class Solution {    /**     * @param root: The root of binary tree.     * @return: An integer.     */    private class ResultType {        int singlePath, maxPath;        ResultType(int singlePath, int maxPath) {            this.singlePath = singlePath;            this.maxPath = maxPath;        }    }    private ResultType helper(TreeNode root) {        if (root == null) {            return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);        }        // Divide        ResultType left = helper(root.left);        ResultType right = helper(root.right);        // Conquer        int singlePath =            Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;        int maxPath = Math.max(left.maxPath, right.maxPath);        maxPath = Math.max(maxPath,                           Math.max(left.singlePath, 0) +                            Math.max(right.singlePath, 0) + root.val);        return new ResultType(singlePath, maxPath);    }    public int maxPathSum(TreeNode root) {        ResultType result = helper(root);        return result.maxPath;    }}

类似的一题为求两个节点的最近公共祖先(LCA),也可以使用ResultType避免对每个节点多次递归。

分治法中使用resultType来让一次递归返回多个结果