LeetCode——Binary Tree Maximum Path Sum

链接:http://leetcode.com/onlinejudge#question_124

原题:

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.

解题思路:

一上来,我是借鉴求数组最大子序列和的方法,来解这个问题的,但是只能过小数据,大数据老是TLE

我的代码

/**
 * 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) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (root == NULL)
            return 0;
        max = root->val;
        maxPath(root);
        
        return max;
    }
    
private:
    void maxPath(TreeNode *root) {
        if (root == NULL)
            return;
            
        vector<int> leftPath;
        int leftTail = 0;
        subPath(root->left, leftPath, leftTail);
        
        vector<int> rightPath;
        int rightTail = 0;
        subPath(root->right, rightPath, rightTail);
        
        if (leftTail + root->val + rightTail > max)
            max = leftTail + root->val + rightTail;

        maxPath(root->left);
        maxPath(root->right);
    }

    void subPath(TreeNode *root, vector<int> &path, int &maxTail) {
        if (root == NULL)
            return;
        path.push_back(root->val);
        if (root->left || root->right) {
            subPath(root->left, path, maxTail);
            subPath(root->right, path, maxTail);
        } else {
            int sum = 0;
            for (vector<int>::reverse_iterator itr = path.rbegin(); itr != path.rend(); itr++) {
                sum += *itr;
                if (sum > max)
                    max = sum;
                if (sum < 0)
                    sum = 0;
            }
            if (sum > maxTail)
                maxTail = sum;
        }
        path.pop_back();
    }
    
    int max;
};

后来是借鉴了这位大牛( http://blog.csdn.net/zyfo2/article/details/8636205)的代码,才过的。

具体思路:
对于每一个节点来说,最大路径和只有出现在这三种情况:

1) 在其左子树当中;

2) 在其右子树当中;

3) 最大和路径经过这个节点。

现在考虑第三情况,其它两种都是递归可得的子问题,

不妨设该节点为Node,左子树到该节点的任意一条路径为 leftPath = {L1, L2, ..., Ln, Node}

同样,右子树到该节点的任意一条路径为 rightPath = {Node, Rm, ..., R2, R1}

现在要求过Node的最大路径和,那么可以从两边往中间走,这样正好可以用递归实现。

int rightTail = 0;
for (int i=1; i<=m; i++) {
     rightTail += Ri;
     if (rightTail < 0)
          rightTail = 0
}

int leftTail = 0;
for (int i=1; i<=n; i++) {
     leftTail += Li;
     if (leftTail < 0)
          leftTail = 0
}

sum = leftTail + Node + rightTail
原理:如果路径要想向左右两个扩展,那么扩展部分的和肯定是个正值,否则路径和不会变大。


AC的代码:

/**
 * 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) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (root == NULL)
            return 0;
        int max = root->val;
        getPathSum(root, max);
        return max;
    }

private:
    int getPathSum(TreeNode *root, int &max) {
        if (root == NULL)
            return 0;
        int leftSum = getPathSum(root->left, max);
        int rightSum = getPathSum(root->right, max);
        if (leftSum + root->val + rightSum > max)
            max = leftSum + root->val + rightSum;
        int subPathSum = leftSum > rightSum ? leftSum : rightSum;
        subPathSum += root->val;
        return subPathSum > 0 ? subPathSum : 0;
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值