您的位置:首页 > 其它

LeetCode 124. Binary Tree Maximum Path Sum

2016-03-29 11:13 239 查看

1. 题目描述

Given a 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 does not need to go through the root.

For example:

Given the below binary tree,

1
/ \
2   3


Return 6.

2. 解题思路

拿到这道题目, 基本的想法还是使用递归, 我们递归计算通过每个节点的最大路径和 ( left + right + val), 与通过该节点的最大子路径的分支(max(left, right) + val), 每次更新一下最大路径和就可以了。考虑到, 可能会有大量重复分支被计算, 我们这里借助一个map存放每个节点 的 左右最大子路径的分支的和。 ie, 使用带备忘录的自上而下的递归算法。

3. code

特别注意, 如果不加 mymap.clear(), vs2013 和 leetcode 都是可以出正确结果的, 但是牛课的oj 不可以, 以后还是尽量注意下初始化的问题好了。

class Solution {
public:
int maxPathSum(TreeNode* root) {
mymap.clear(); // 这句话一定要加, 如果不加的牛课的OJ 通过不了
int maxsum = root->val;
computePathSum(root, maxsum);
return maxsum;
}

private:

//************************************
// Method:    computePathSum
// FullName:  Solution::computePathSum
// Access:    private
// Returns:   int   返回经过 root 的下方路径中最大的值
// Qualifier:
// Parameter: TreeNode * root
// Parameter: int & maxsum 记录所经过的所有路径的最大值
//************************************
int computePathSum(TreeNode * root, int & maxsum){
if (root == nullptr)
return 0;

if (mymap.find(root) == mymap.end()){
// 因为经过 root->left 的节点可能会小于 0, 这时候, 这部分节点可以不用遍历了
//  直接从root 节点出发就可以了
int left = max(computePathSum(root->left, maxsum), 0);
int right = max(computePathSum(root->right, maxsum), 0);
mymap.insert(make_pair(root, vector<int>{left, right}));
}
// 计算路径 root 节点的 path 的最长路径和
int sum = mymap[root][0] + mymap[root][1] + root->val;
// 更新 maxsum
maxsum = maxsum >= sum ? maxsum : sum;
// 返回root 路径下方最长的路径和
return max(mymap[root][0], mymap[root][1]) + root->val;
}

unordered_map<TreeNode *, vector<int>> mymap;
};


4. 大神代码

虽然理论上使用带备忘录的递归算法, 效率应该更快些, 不过这里似乎不是这样, 这段代码比我们快很多。也就是说, 我们的代码中维护一个map 消耗掉的时间效率是巨大的。

int maxPathSum(TreeNode *root) {
int maxPath = INT_MIN;
dfsMaxPath(root, maxPath);
return maxPath;
}

int dfsMaxPath(TreeNode *root, int &maxPath) {
if (!root) return 0;
int l = max(0, dfsMaxPath(root->left, maxPath));
int r = max(0, dfsMaxPath(root->right, maxPath));
maxPath = max(maxPath, l + r + root->val);
return root->val + max(l, r);
}


同时需要注意的是:

maxsum = maxsum >= sum ? maxsum : sum;
maxsum = max(maxsum, sum);


他们两者之间也是存在差别的, 我们提交之后, 可以看到仅仅因为这句话的不同, 运行时间差了10ms

我们查看了下他们的反汇编代码, 发现:



差别果然还是蛮大的, 以后还是尽量使用标准库好了=_=!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: