Skip to content

Commit 2fec556

Browse files
authored
feat: add solutions to lcof2 problems: No.50,51 (#1512)
* No.50.路径总和III * No.51.节点之和最大的路径
1 parent 4b6d5a6 commit 2fec556

File tree

14 files changed

+584
-144
lines changed

14 files changed

+584
-144
lines changed

lcof2/剑指 Offer II 050. 向下的路径节点之和/README.md

+36
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,42 @@ func pathSum(root *TreeNode, targetSum int) int {
200200
}
201201
```
202202

203+
### **TypeScript**
204+
205+
```ts
206+
/**
207+
* Definition for a binary tree node.
208+
* class TreeNode {
209+
* val: number
210+
* left: TreeNode | null
211+
* right: TreeNode | null
212+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
213+
* this.val = (val===undefined ? 0 : val)
214+
* this.left = (left===undefined ? null : left)
215+
* this.right = (right===undefined ? null : right)
216+
* }
217+
* }
218+
*/
219+
220+
function pathSum(root: TreeNode | null, targetSum: number): number {
221+
const cnt: Map<number, number> = new Map();
222+
const dfs = (node: TreeNode | null, s: number): number => {
223+
if (!node) {
224+
return 0;
225+
}
226+
s += node.val;
227+
let ans = cnt.get(s - targetSum) ?? 0;
228+
cnt.set(s, (cnt.get(s) ?? 0) + 1);
229+
ans += dfs(node.left, s);
230+
ans += dfs(node.right, s);
231+
cnt.set(s, (cnt.get(s) ?? 0) - 1);
232+
return ans;
233+
};
234+
cnt.set(0, 1);
235+
return dfs(root, 0);
236+
}
237+
```
238+
203239
### **...**
204240

205241
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* class TreeNode {
4+
* val: number
5+
* left: TreeNode | null
6+
* right: TreeNode | null
7+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
8+
* this.val = (val===undefined ? 0 : val)
9+
* this.left = (left===undefined ? null : left)
10+
* this.right = (right===undefined ? null : right)
11+
* }
12+
* }
13+
*/
14+
15+
function pathSum(root: TreeNode | null, targetSum: number): number {
16+
const cnt: Map<number, number> = new Map();
17+
const dfs = (node: TreeNode | null, s: number): number => {
18+
if (!node) {
19+
return 0;
20+
}
21+
s += node.val;
22+
let ans = cnt.get(s - targetSum) ?? 0;
23+
cnt.set(s, (cnt.get(s) ?? 0) + 1);
24+
ans += dfs(node.left, s);
25+
ans += dfs(node.right, s);
26+
cnt.set(s, (cnt.get(s) ?? 0) - 1);
27+
return ans;
28+
};
29+
cnt.set(0, 1);
30+
return dfs(root, 0);
31+
}

lcof2/剑指 Offer II 051. 节点之和最大的路径/README.md

+203-51
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,27 @@
4848

4949
<!-- 这里可写通用的实现逻辑 -->
5050

51-
思考二叉树递归问题的经典套路:
51+
**方法一:递归**
52+
53+
我们思考二叉树递归问题的经典套路:
5254

5355
1. 终止条件(何时终止递归)
5456
2. 递归处理左右子树
5557
3. 合并左右子树的计算结果
5658

57-
对于本题,由于要满足题目对“路径”的定义,在返回当前子树对外贡献的最大路径和时,需要取 `left``right` 的最大值
59+
对于本题,我们设计一个函数 $dfs(root)$,它返回以 $root$ 为根节点的二叉树的最大路径和。
60+
61+
函数 $dfs(root)$ 的执行逻辑如下:
62+
63+
如果 $root$ 不存在,那么 $dfs(root)$ 返回 $0$;
64+
65+
否则,我们递归计算 $root$ 的左子树和右子树的最大路径和,分别记为 $left$ 和 $right$。如果 $left$ 小于 $0$,那么我们将其置为 $0$,同理,如果 $right$ 小于 $0$,那么我们将其置为 $0$。
66+
67+
然后,我们用 $root.val + left + right$ 更新答案。最后,函数返回 $root.val + \max(left, right)$。
68+
69+
在主函数中,我们调用 $dfs(root)$,即可得到每个节点的最大路径和,其中的最大值即为答案。
70+
71+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
5872

5973
<!-- tabs:start -->
6074

@@ -70,18 +84,17 @@
7084
# self.left = left
7185
# self.right = right
7286
class Solution:
73-
def maxPathSum(self, root: TreeNode) -> int:
74-
ans = -inf
75-
76-
def dfs(node: TreeNode) -> int:
77-
if not node:
87+
def maxPathSum(self, root: Optional[TreeNode]) -> int:
88+
def dfs(root: Optional[TreeNode]) -> int:
89+
if root is None:
7890
return 0
79-
left = max(0, dfs(node.left))
80-
right = max(0, dfs(node.right))
91+
left = max(0, dfs(root.left))
92+
right = max(0, dfs(root.right))
8193
nonlocal ans
82-
ans = max(ans, node.val + left + right)
83-
return node.val + max(left, right)
94+
ans = max(ans, root.val + left + right)
95+
return root.val + max(left, right)
8496

97+
ans = -inf
8598
dfs(root)
8699
return ans
87100
```
@@ -107,25 +120,58 @@ class Solution:
107120
* }
108121
*/
109122
class Solution {
110-
private int ans = Integer.MIN_VALUE;
123+
private int ans = -1001;
111124

112125
public int maxPathSum(TreeNode root) {
113126
dfs(root);
114127
return ans;
115128
}
116129

117-
private int dfs(TreeNode node) {
118-
if (node == null) {
130+
private int dfs(TreeNode root) {
131+
if (root == null) {
119132
return 0;
120133
}
121-
int left = Math.max(0, dfs(node.left));
122-
int right = Math.max(0, dfs(node.right));
123-
ans = Math.max(ans, node.val + left + right);
124-
return node.val + Math.max(left, right);
134+
int left = Math.max(0, dfs(root.left));
135+
int right = Math.max(0, dfs(root.right));
136+
ans = Math.max(ans, root.val + left + right);
137+
return root.val + Math.max(left, right);
125138
}
126139
}
127140
```
128141

142+
### **C++**
143+
144+
```cpp
145+
/**
146+
* Definition for a binary tree node.
147+
* struct TreeNode {
148+
* int val;
149+
* TreeNode *left;
150+
* TreeNode *right;
151+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
152+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
153+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
154+
* };
155+
*/
156+
class Solution {
157+
public:
158+
int maxPathSum(TreeNode* root) {
159+
int ans = -1001;
160+
function<int(TreeNode*)> dfs = [&](TreeNode* root) {
161+
if (!root) {
162+
return 0;
163+
}
164+
int left = max(0, dfs(root->left));
165+
int right = max(0, dfs(root->right));
166+
ans = max(ans, left + right + root->val);
167+
return root->val + max(left, right);
168+
};
169+
dfs(root);
170+
return ans;
171+
}
172+
};
173+
```
174+
129175
### **Go**
130176
131177
```go
@@ -138,19 +184,17 @@ class Solution {
138184
* }
139185
*/
140186
func maxPathSum(root *TreeNode) int {
141-
ans := math.MinInt32
142-
187+
ans := -1001
143188
var dfs func(*TreeNode) int
144-
dfs = func(node *TreeNode) int {
145-
if node == nil {
189+
dfs = func(root *TreeNode) int {
190+
if root == nil {
146191
return 0
147192
}
148-
left := max(0, dfs(node.Left))
149-
right := max(0, dfs(node.Right))
150-
ans = max(ans, node.Val+left+right)
151-
return node.Val + max(left, right)
193+
left := max(0, dfs(root.Left))
194+
right := max(0, dfs(root.Right))
195+
ans = max(ans, left+right+root.Val)
196+
return max(left, right) + root.Val
152197
}
153-
154198
dfs(root)
155199
return ans
156200
}
@@ -163,39 +207,147 @@ func max(a, b int) int {
163207
}
164208
```
165209

166-
### **C++**
210+
### **TypeScript**
167211

168-
```cpp
212+
```ts
169213
/**
170214
* Definition for a binary tree node.
171-
* struct TreeNode {
172-
* int val;
173-
* TreeNode *left;
174-
* TreeNode *right;
175-
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
176-
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
177-
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
178-
* };
215+
* class TreeNode {
216+
* val: number
217+
* left: TreeNode | null
218+
* right: TreeNode | null
219+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
220+
* this.val = (val===undefined ? 0 : val)
221+
* this.left = (left===undefined ? null : left)
222+
* this.right = (right===undefined ? null : right)
223+
* }
224+
* }
179225
*/
180-
class Solution {
181-
public:
182-
int maxPathSum(TreeNode* root) {
183-
int ans = INT_MIN;
184226

185-
function<int(TreeNode*)> dfs = [&](TreeNode* node) {
186-
if (node == nullptr) {
187-
return 0;
188-
}
189-
int left = max(0, dfs(node->left));
190-
int right = max(0, dfs(node->right));
191-
ans = max(ans, node->val + left + right);
192-
return node->val + max(left, right);
193-
};
227+
function maxPathSum(root: TreeNode | null): number {
228+
let ans = -1001;
229+
const dfs = (root: TreeNode | null): number => {
230+
if (!root) {
231+
return 0;
232+
}
233+
const left = Math.max(0, dfs(root.left));
234+
const right = Math.max(0, dfs(root.right));
235+
ans = Math.max(ans, left + right + root.val);
236+
return Math.max(left, right) + root.val;
237+
};
238+
dfs(root);
239+
return ans;
240+
}
241+
```
242+
243+
### **JavaScript**
244+
245+
```js
246+
/**
247+
* Definition for a binary tree node.
248+
* function TreeNode(val, left, right) {
249+
* this.val = (val===undefined ? 0 : val)
250+
* this.left = (left===undefined ? null : left)
251+
* this.right = (right===undefined ? null : right)
252+
* }
253+
*/
254+
/**
255+
* @param {TreeNode} root
256+
* @return {number}
257+
*/
258+
var maxPathSum = function (root) {
259+
let ans = -1001;
260+
const dfs = root => {
261+
if (!root) {
262+
return 0;
263+
}
264+
const left = Math.max(0, dfs(root.left));
265+
const right = Math.max(0, dfs(root.right));
266+
ans = Math.max(ans, left + right + root.val);
267+
return Math.max(left, right) + root.val;
268+
};
269+
dfs(root);
270+
return ans;
271+
};
272+
```
273+
274+
### **C#**
194275

276+
```cs
277+
/**
278+
* Definition for a binary tree node.
279+
* public class TreeNode {
280+
* public int val;
281+
* public TreeNode left;
282+
* public TreeNode right;
283+
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
284+
* this.val = val;
285+
* this.left = left;
286+
* this.right = right;
287+
* }
288+
* }
289+
*/
290+
public class Solution {
291+
private int ans = -1001;
292+
293+
public int MaxPathSum(TreeNode root) {
195294
dfs(root);
196295
return ans;
197296
}
198-
};
297+
298+
private int dfs(TreeNode root) {
299+
if (root == null) {
300+
return 0;
301+
}
302+
int left = Math.Max(0, dfs(root.left));
303+
int right = Math.Max(0, dfs(root.right));
304+
ans = Math.Max(ans, left + right + root.val);
305+
return root.val + Math.Max(left, right);
306+
}
307+
}
308+
```
309+
310+
### **Rust**
311+
312+
```rust
313+
// Definition for a binary tree node.
314+
// #[derive(Debug, PartialEq, Eq)]
315+
// pub struct TreeNode {
316+
// pub val: i32,
317+
// pub left: Option<Rc<RefCell<TreeNode>>>,
318+
// pub right: Option<Rc<RefCell<TreeNode>>>,
319+
// }
320+
//
321+
// impl TreeNode {
322+
// #[inline]
323+
// pub fn new(val: i32) -> Self {
324+
// TreeNode {
325+
// val,
326+
// left: None,
327+
// right: None
328+
// }
329+
// }
330+
// }
331+
use std::rc::Rc;
332+
use std::cell::RefCell;
333+
impl Solution {
334+
fn dfs(root: &Option<Rc<RefCell<TreeNode>>>, res: &mut i32) -> i32 {
335+
if root.is_none() {
336+
return 0;
337+
}
338+
let node = root.as_ref().unwrap().borrow();
339+
let left = 0.max(Self::dfs(&node.left, res));
340+
let right = 0.max(Self::dfs(&node.right, res));
341+
*res = (node.val + left + right).max(*res);
342+
node.val + left.max(right)
343+
}
344+
345+
pub fn max_path_sum(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
346+
let mut res = -1000;
347+
Self::dfs(&root, &mut res);
348+
res
349+
}
350+
}
199351
```
200352

201353
### **...**

0 commit comments

Comments
 (0)