Skip to content

Commit 04093cd

Browse files
committed
solve #124
1 parent 2f4746e commit 04093cd

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,4 @@ mod n0120_triangle;
122122
mod n0121_best_time_to_buy_and_sell_stock;
123123
mod n0122_best_time_to_buy_and_sell_stock_ii;
124124
mod n0123_best_time_to_buy_and_sell_stock_iii;
125+
mod n0124_binary_tree_maximum_path_sum;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* [124] Binary Tree Maximum Path Sum
3+
*
4+
* Given a non-empty binary tree, find the maximum path sum.
5+
*
6+
* 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.
7+
*
8+
* Example 1:
9+
*
10+
*
11+
* Input: [1,2,3]
12+
*
13+
* 1
14+
* / \
15+
* 2 3
16+
*
17+
* Output: 6
18+
*
19+
*
20+
* Example 2:
21+
*
22+
*
23+
* Input: [-10,9,20,null,null,15,7]
24+
*
25+
* -10
26+
* / \
27+
* 9 20
28+
* / \
29+
* 15 7
30+
*
31+
* Output: 42
32+
*
33+
*
34+
*/
35+
pub struct Solution {}
36+
use super::util::tree::{TreeNode, to_tree};
37+
38+
// submission codes start here
39+
40+
/*
41+
典型的动态规划, 我们求以 node_i 为 root 的最大和, 可以下推到求 root 的左右子树, 这里要注意, 路径是不能分叉的, 因此
42+
我们记 f[node] 为以 node 为根的最大和, 记 g[node] 为 node 为根, *最多连通一侧子树*的最大和
43+
44+
我们在递推时要用 g[node], f[node] 在递推过程中每次计算一下用于更新 max 即可
45+
46+
g[node_i] = node_i.val + max(g[node_i.left], g[node_i.right], 0)
47+
f[node_i] = node_i.val + max(g[node_i.left], 0) + max(g[node_i.right], 0)
48+
49+
显然, g[None] = 0 (None 即空子树), 最终计算到 g[root] 中止, f 的最大值会在计算过程中出现(注意 f[root] 不一定是最大值)
50+
51+
每个 node 最大和只依赖与其左右子树的最大和, 因此 Top-down 需要 O(N) 的空间
52+
Bottom-up 只需要 O(1) 空间 (做后序遍历从叶节点向上递推即可)
53+
*/
54+
use std::rc::Rc;
55+
use std::cell::RefCell;
56+
impl Solution {
57+
pub fn max_path_sum(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
58+
let mut max = i32::min_value();
59+
Solution::postorder(root.as_ref(), &mut max);
60+
max
61+
}
62+
63+
fn postorder(root: Option<&Rc<RefCell<TreeNode>>>, max: &mut i32) -> i32 {
64+
if let Some(node) = root {
65+
let left = Solution::postorder(node.borrow().left.as_ref(), max);
66+
let right = Solution::postorder(node.borrow().right.as_ref(), max);
67+
*max = i32::max(node.borrow().val + i32::max(left, 0) + i32::max(right, 0), *max);
68+
node.borrow().val + i32::max(i32::max(left, right), 0)
69+
} else {
70+
0
71+
}
72+
}
73+
}
74+
75+
// submission codes end
76+
77+
#[cfg(test)]
78+
mod tests {
79+
use super::*;
80+
81+
#[test]
82+
fn test_124() {
83+
assert_eq!(Solution::max_path_sum(tree![1,2,3]), 6);
84+
assert_eq!(Solution::max_path_sum(tree![-10,9,20,null,null,15,7]), 42);
85+
assert_eq!(Solution::max_path_sum(tree![5,4,8,11,null,13,4,7,2,null,null,null,1]), 48);
86+
assert_eq!(Solution::max_path_sum(tree![-3]), -3);
87+
}
88+
}

0 commit comments

Comments
 (0)