zoukankan      html  css  js  c++  java
  • 二叉树系列

    题目:

    Binary Tree Maximum Path Sum

    Given a binary tree, find the maximum path sum.

    The path may start and end at any node in the tree.

    For example:
    Given the below binary tree,

           1
          / 
         2   3
    

    Return 6.

    节点可能为负数,寻找一条最路径使得所经过节点和最大。路径可以开始和结束于任何节点但是不能走回头路。

    这道题虽然看起来不同寻常,但是想一下,可以发现不外乎二叉树的遍历+简单的动态规划思想。

    我们可以把问题拆分开:即便最后的最大路径没有经过根节点,它必然也有自己的“最高点”,因此我们只要针对所有结点,求出:如果路径把这个节点作为“最高点”,路径最长可达多少?记为max。然后在max中求出最大值MAX即为所求结果。和“求整数序列中的最大连续子序列”一样思路。

    下面就是找各个“最高点”对应的max之间的关系了。

    我们拿根节点为例,对于经过根节点的最大路径的计算方式为:

    我们找出左子树中以左孩子为起点的最大路径长度a,和右子树中以右孩子为起点的最大路径长度b。然后这个点的 max = MAX(a+b+node.val, a+node.val, b+node.val, node.val)

    因此我们定义一个函数来算上面的a或者b,它的参数是一个节点,它的返回值是最大路径长度,但是这个路径的起点必须是输入节点,而且路径必须在以起点为根节点的子树上。

    那么函数func(node)的return值可以这样定义:return MAX(func(node.left)+node.val, func(node.right)+node.val, node.val)

    终止条件是node == null,直接返回0。

    接着我们发现上述计算max 和 求出MAX的过程完全可以放到func(node) 里去。

    按照这个思路的代码,maxPathSumCore 就是上面 func(node)的实现:

    /**
     * Definition for binary tree
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int maxPathSum(TreeNode *root) {
            maxPathSumCore(root);
            return MAX;
        }
        int maxPathSumCore(TreeNode *node) {
            if(NULL == node) return 0;
            int a = maxPathSumCore(node -> left);
            int b = maxPathSumCore(node -> right);
            if((a+b+node->val) > MAX) MAX = (a+b+node->val);
            if((a+node->val) > MAX) MAX = (a+node->val);
            if((b+node->val) > MAX) MAX = (b+node->val);
            if(node->val > MAX) MAX = node->val;
    int maxViaThisNode = ((a + node->val) > node->val ? (a + node->val) : node->val); return (maxViaThisNode > (b + node->val) ? maxViaThisNode : (b + node->val)); } private: int MAX= -99999999; };

     时间复杂度 O(n),n为总节点数。

  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/felixfang/p/3637984.html
Copyright © 2011-2022 走看看