zoukankan      html  css  js  c++  java
  • leetcode124

    Given a non-empty binary tree, find the maximum path sum.
    For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
    Example 1:
    Input: [1,2,3]

    1
    /
    2 3
    Output: 6
    Example 2:
    Input: [-10,9,20,null,null,15,7]
    -10
    /
    9 20
    /
    15 7
    Output: 42

    树的分治法。DFS。
    对某个root而言,定义one:包含该root往左右某一方向延伸,延伸到任意长度这条链上的和的最大值。two:包含该root往左右都延伸,延伸到任意长度这条链上和的最大值(只考虑严格双边的情况)。那么:
    one = max(root.val, root.val + left.one如果有, root.val + right.one如果有)
    two = max(root.val, root.val + left.one + right.one如果两边都有) (不用考虑退化成单边的形式,one已经帮你处理了)
    在计算one,two的过程中给全局变量打个擂台,最后返回全局最大one和全局最大two其中大的那个。

    细节:
    1.因为观察计算,所需要的子数据只有one,所以不用新建resultType类,直接每次只返回one即可。two只是算一下打个全局擂台就抛弃了。
    2.root == null的情况下不可以直接返回0. 如果返回0,那对负数的叶子节点比如-3,那这个按这样算出来的one, two结果就被抬高到0了,不正确。所以定义返回类型为Integer而不是int,这样碰null返null区分一下。同时这种情况下代码里每个地方写int还是写Integer都小心一点,避免自动转换类型造成代码错误。
    3.最后的答案是全局打擂台产生的,而不是根节点的one, two其中之一。因为one的定义是带跟的,你要按这个错误的方法算的话那你就忽略了中间某段游离的one的情况了。

    实现:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        
        private int oneMax = Integer.MIN_VALUE;
        private int twoMax = Integer.MIN_VALUE;
        
        public int maxPathSum(TreeNode root) {
            dfs(root);
            // P3: 答案不是root的one two其中大的那个,而应该是dfs过程中打擂台产生的。因为one的定义是经过root的一长条,那么这要求答案样子要么是经过root的,没有考虑到中间某一段one条。
            return Math.max(oneMax, twoMax);
        }
        
        // P3: 巧妙用Integer类型的null表示null节点。
        private Integer dfs(TreeNode root) {
            if (root == null) {
                // P1: 不可以return(0, 0),这样对负数的叶子节点不正确,把它们的one, two值抬高到0了。
                // return new ResultType(0, 0);
                return null;
            }
            // P2: 这里别写成int left,那下面就对比不了null了。
            Integer left = dfs(root.left);
            Integer right = dfs(root.right);
            int one = root.val, two = root.val;
            if (left != null) {
                one = Math.max(one, root.val + left);
            }
            if (right != null) {
                one = Math.max(one, root.val + right);
            }
            if (left != null && right != null) {
                two = Math.max(two, root.val + left + right);
            }
            oneMax = Math.max(oneMax, one);
            twoMax = Math.max(twoMax, two);
            return one;
        }
    }
  • 相关阅读:
    WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
    事件(Event),绝大多数内存泄漏(Memory Leak)的元凶[上篇]
    谈谈关于MVP模式中VP交互问题
    如何通过VPC在本机搭建局域网
    谈谈分布式事务之三: System.Transactions事务详解[下篇]
    WCF版的PetShop之二:模块中的层次划分[提供源代码下载]
    实践重于理论——创建一个监控程序探测WCF的并发处理机制
    WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[WS标准篇]
    WCF技术剖析之三十一: WCF事务编程[中篇]
    微软将结束对Windows 2000、XP和Vista部份版本的技术支持
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9656038.html
Copyright © 2011-2022 走看看