Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit29f3c9e

Browse files
Update
1 parenta54fe17 commit29f3c9e

File tree

3 files changed

+155
-2
lines changed

3 files changed

+155
-2
lines changed

‎README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@
6262
*[字符串:替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg)
6363
*[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)
6464
*[字符串:反转个字符串还有这个用处?](https://mp.weixin.qq.com/s/PmcdiWSmmccHAONzU0ScgQ)
65-
*[字符串:KMP是时候上场了(一文读懂系列)](https://mp.weixin.qq.com/s/70OXnZ4Ez29CKRrUpVJmug)
65+
*[帮你把KMP算法学个通透!(理论篇)B站视频](https://www.bilibili.com/video/BV1PD4y1o7nd)
66+
*[帮你把KMP算法学个通透!(代码篇)B站视频](https://www.bilibili.com/video/BV1M5411j7Xx)
6667
*[字符串:都来看看KMP的看家本领!](https://mp.weixin.qq.com/s/Gk9FKZ9_FSWLEkdGrkecyg)
67-
*[字符串:听说你对KMP有这些疑问?](https://mp.weixin.qq.com/s/mqx6IM2AO4kLZwvXdPtEeQ)
6868
*[字符串:KMP算法还能干这个!](https://mp.weixin.qq.com/s/lR2JPtsQSR2I_9yHbBmBuQ)
6969
*[字符串:前缀表不右移,难道就写不出KMP了?](https://mp.weixin.qq.com/s/p3hXynQM2RRROK5c6X7xfw)
7070
*[字符串:总结篇!](https://mp.weixin.qq.com/s/gtycjyDtblmytvBRFlCZJg)
59.5 KB
Loading
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
2+
##思路
3+
4+
本题和[113.路径总和II](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0113.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8CII.md)是类似的思路,做完这道题,可以顺便把[113.路径总和II](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0113.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8CII.md)[112.路径总和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0112.路径总和.md) 做了。
5+
6+
结合112.路径总和 和 113.路径总和II,我在讲了[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg),如果大家对二叉树递归函数什么时候需要返回值很迷茫,可以看一下。
7+
8+
接下来在看本题,就简单多了,本题其实需要使用回溯,但一些同学可能都不知道自己用了回溯,在[二叉树:以为使用了递归,其实还隐藏着回溯](https://mp.weixin.qq.com/s/ivLkHzWdhjQQD1rQWe6zWA)中,我详细讲解了二叉树的递归中,如何使用了回溯。
9+
10+
接下来我们来看题:
11+
12+
首先思路很明确,就是要遍历整个树把更节点到叶子节点组成的数字相加。
13+
14+
那么先按递归三部曲来分析:
15+
16+
###递归三部曲
17+
18+
如果对递归三部曲不了解的话,可以看这里:[二叉树:前中后递归详解](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)
19+
20+
* 确定递归函数返回值及其参数
21+
22+
这里我们要遍历整个二叉树,且需要要返回值做逻辑处理,所有返回值为void,在[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg)中,详细讲解了返回值问题。
23+
24+
参数只需要把根节点传入,此时还需要定义两个全局遍历,一个是result,记录最终结果,一个是vector<int> path。
25+
26+
**为什么用vector类型(就是数组)呢? 因为用vector方便我们做回溯!**
27+
28+
所以代码如下:
29+
30+
```
31+
int result;
32+
vector<int> path;
33+
void traversal(TreeNode* cur)
34+
```
35+
36+
* 确定终止条件
37+
38+
递归什么时候终止呢?
39+
40+
当然是遇到叶子节点,此时要收集结果了,通知返回本层递归,因为单条路径的结果使用vector,我们需要一个函数vectorToInt把vector转成int。
41+
42+
终止条件代码如下:
43+
44+
```
45+
if (!cur->left && !cur->right) { // 遇到了叶子节点
46+
result += vectorToInt(path);
47+
return;
48+
}
49+
```
50+
51+
这里vectorToInt函数就是把数组转成int,代码如下:
52+
53+
```
54+
int vectorToInt(const vector<int>& vec) {
55+
int sum = 0;
56+
for (int i = 0; i < vec.size(); i++) {
57+
sum = sum * 10 + vec[i];
58+
}
59+
return sum;
60+
}
61+
```
62+
63+
64+
* 确定递归单层逻辑
65+
66+
本题其实采用前中后序都不无所谓, 因为也没有中间几点的处理逻辑。
67+
68+
这里主要是当左节点不为空,path收集路径,并递归左孩子,右节点同理。
69+
70+
**但别忘了回溯**
71+
72+
如图:
73+
74+
75+
<imgsrc='../pics/129.求根到叶子节点数字之和.png'width=600> </img></div>
76+
77+
代码如下:
78+
79+
```
80+
// 中
81+
if (cur->left) { // 左 (空节点不遍历)
82+
path.push_back(cur->left->val);
83+
traversal(cur->left); // 递归
84+
path.pop_back(); // 回溯
85+
}
86+
if (cur->right) { // 右 (空节点不遍历)
87+
path.push_back(cur->right->val);
88+
traversal(cur->right); // 递归
89+
path.pop_back(); // 回溯
90+
}
91+
```
92+
93+
这里要注意回溯和递归要永远在一起,一个递归,对应一个回溯,是一对一的关系,有的同学写成如下代码:
94+
95+
```
96+
if (cur->left) { // 左 (空节点不遍历)
97+
path.push_back(cur->left->val);
98+
traversal(cur->left); // 递归
99+
}
100+
if (cur->right) { // 右 (空节点不遍历)
101+
path.push_back(cur->right->val);
102+
traversal(cur->right); // 递归
103+
}
104+
path.pop_back(); // 回溯
105+
```
106+
**把回溯放在花括号外面了,世界上最遥远的距离,是你在花括号里,而我在花括号外!** 这就不对了。
107+
108+
###整体C++代码
109+
110+
关键逻辑分析完了,整体C++代码如下:
111+
112+
```
113+
class Solution {
114+
private:
115+
int result;
116+
vector<int> path;
117+
// 把vector转化为int
118+
int vectorToInt(const vector<int>& vec) {
119+
int sum = 0;
120+
for (int i = 0; i < vec.size(); i++) {
121+
sum = sum * 10 + vec[i];
122+
}
123+
return sum;
124+
}
125+
// 递归函数不需要返回值,因为我们要遍历整个树
126+
void traversal(TreeNode* cur) {
127+
if (!cur->left && !cur->right) { // 遇到了叶子节点
128+
result += vectorToInt(path);
129+
return;
130+
}
131+
132+
if (cur->left) { // 左 (空节点不遍历)
133+
path.push_back(cur->left->val);
134+
traversal(cur->left); // 递归
135+
path.pop_back(); // 回溯
136+
}
137+
if (cur->right) { // 右 (空节点不遍历)
138+
path.push_back(cur->right->val);
139+
traversal(cur->right); // 递归
140+
path.pop_back(); // 回溯
141+
}
142+
return ;
143+
}
144+
public:
145+
int sumNumbers(TreeNode* root) {
146+
path.clear();
147+
if (root == nullptr) return 0;
148+
path.push_back(root->val);
149+
traversal(root);
150+
return result;
151+
}
152+
};
153+
```

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp