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

Commitcf4f84f

Browse files
Update
1 parent398cf1a commitcf4f84f

File tree

2 files changed

+412
-24
lines changed

2 files changed

+412
-24
lines changed
Lines changed: 115 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,88 @@
1+
#二叉树:以为使用了递归,其实还隐藏着回溯
12

2-
在上一面
3+
>补充一波
34
5+
昨天的总结篇中[还在玩耍的你,该总结啦!(本周小结之二叉树)](https://mp.weixin.qq.com/s/QMBUTYnoaNfsVHlUADEzKg),有两处问题需要说明一波。
6+
7+
##求相同的树
8+
9+
[还在玩耍的你,该总结啦!(本周小结之二叉树)](https://mp.weixin.qq.com/s/QMBUTYnoaNfsVHlUADEzKg)中求100.相同的树的代码中,我笔误贴出了 求对称树的代码了,细心的同学应该都发现了。
10+
11+
那么如下我再给出求100. 相同的树 的代码,如下:
12+
13+
```
14+
class Solution {
15+
public:
16+
bool compare(TreeNode* tree1, TreeNode* tree2) {
17+
if (tree1 == NULL && tree2 != NULL) return false;
18+
else if (tree1 != NULL && tree2 == NULL) return false;
19+
else if (tree1 == NULL && tree2 == NULL) return true;
20+
else if (tree1->val != tree2->val) return false; // 注意这里我没有使用else
21+
22+
// 此时就是:左右节点都不为空,且数值相同的情况
23+
// 此时才做递归,做下一层的判断
24+
bool compareLeft = compare(tree1->left, tree2->left); // 左子树:左、 右子树:左
25+
bool compareRight = compare(tree1->right, tree2->right); // 左子树:右、 右子树:右
26+
bool isSame = compareLeft && compareRight; // 左子树:中、 右子树:中(逻辑处理)
27+
return isSame;
28+
29+
}
30+
bool isSameTree(TreeNode* p, TreeNode* q) {
31+
return compare(p, q);
32+
}
33+
};
34+
```
35+
36+
以上的代码相对于:[二叉树:我对称么?](https://mp.weixin.qq.com/s/Kgf0gjvlDlNDfKIH2b1Oxg) 仅仅修改了变量的名字(为了符合判断相同树的语境)和 遍历的顺序。
37+
38+
大家应该会体会到:**认清[判断对称树](https://mp.weixin.qq.com/s/Kgf0gjvlDlNDfKIH2b1Oxg)本质之后, 对称树的代码 稍作修改 就可以直接用来AC 100.相同的树。**
39+
40+
##递归中隐藏着回溯
41+
42+
[二叉树:找我的所有路径?](https://mp.weixin.qq.com/s/Osw4LQD2xVUnCJ-9jrYxJA)中我强调了本题其实是用到了回溯的,并且给出了第一个版本的代码,把回溯的过程充分的提现了出来。
43+
44+
如下的代码充分的体现出回溯:(257. 二叉树的所有路径)
445

546
```
647
class Solution {
748
private:
8-
void traversal(TreeNode* cur, string path, vector<string>& result) {
9-
path += to_string(cur->val); // 中
49+
50+
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
51+
path.push_back(cur->val);
52+
// 这才到了叶子节点
1053
if (cur->left == NULL && cur->right == NULL) {
11-
result.push_back(path);
54+
string sPath;
55+
for (int i = 0; i < path.size() - 1; i++) {
56+
sPath += to_string(path[i]);
57+
sPath += "->";
58+
}
59+
sPath += to_string(path[path.size() - 1]);
60+
result.push_back(sPath);
1261
return;
1362
}
14-
1563
if (cur->left) {
16-
path += "->";
17-
traversal(cur->left, path, result); // 左
64+
traversal(cur->left, path, result);
1865
path.pop_back(); // 回溯
19-
path.pop_back();
2066
}
2167
if (cur->right) {
22-
path += "->";
23-
traversal(cur->right, path, result); // 右
68+
traversal(cur->right, path, result);
2469
path.pop_back(); // 回溯
25-
path.pop_back();
2670
}
2771
}
2872
2973
public:
3074
vector<string> binaryTreePaths(TreeNode* root) {
3175
vector<string> result;
32-
string path;
76+
vector<int> path;
3377
if (root == NULL) return result;
3478
traversal(root, path, result);
3579
return result;
36-
3780
}
3881
};
3982
```
4083

41-
没有回溯了
84+
85+
如下为精简之后的递归代码:(257. 二叉树的所有路径)
4286
```
4387
class Solution {
4488
private:
@@ -48,15 +92,8 @@ private:
4892
result.push_back(path);
4993
return;
5094
}
51-
52-
if (cur->left) {
53-
path += "->";
54-
traversal(cur->left, path, result); // 左
55-
}
56-
if (cur->right) {
57-
path += "->";
58-
traversal(cur->right, path, result); // 右
59-
}
95+
if (cur->left) traversal(cur->left, path + "->", result); // 左 回溯就隐藏在这里
96+
if (cur->right) traversal(cur->right, path + "->", result); // 右 回溯就隐藏在这里
6097
}
6198
6299
public:
@@ -66,7 +103,61 @@ public:
66103
if (root == NULL) return result;
67104
traversal(root, path, result);
68105
return result;
69-
70106
}
71107
};
72108
```
109+
110+
上面的代码,大家貌似感受不到回溯了,其实**回溯就隐藏在traversal(cur->left, path + "->", result);中的 path + "->"。 每次函数调用完,path依然是没有加上"->" 的,这就是回溯了。**
111+
112+
为了把这份精简代码的回溯过程展现出来,大家可以试一试把:
113+
114+
```
115+
if (cur->left) traversal(cur->left, path + "->", result); // 左 回溯就隐藏在这里
116+
```
117+
118+
改成如下代码:
119+
120+
```
121+
path += "->";
122+
traversal(cur->left, path, result); // 左
123+
```
124+
125+
即:
126+
127+
```
128+
129+
if (cur->left) {
130+
path += "->";
131+
traversal(cur->left, path, result); // 左
132+
}
133+
if (cur->right) {
134+
path += "->";
135+
traversal(cur->right, path, result); // 右
136+
}
137+
```
138+
139+
此时就没有回溯了,这个代码就是通过不了的了。
140+
141+
如果想把回溯加上,就要 在上面代码的基础上,加上回溯,就可以AC了。
142+
143+
```
144+
if (cur->left) {
145+
path += "->";
146+
traversal(cur->left, path, result); // 左
147+
path.pop_back(); // 回溯
148+
path.pop_back();
149+
}
150+
if (cur->right) {
151+
path += "->";
152+
traversal(cur->right, path, result); // 右
153+
path.pop_back(); // 回溯
154+
path.pop_back();
155+
}
156+
```
157+
158+
**大家应该可以感受出来,如果把`path + "->"`作为函数参数就是可以的,因为并有没有改变path的数值,执行完递归函数之后,path依然是之前的数值(相当于回溯了)**
159+
160+
如果有点遗忘了,建议把这篇[二叉树:找我的所有路径?](https://mp.weixin.qq.com/s/Osw4LQD2xVUnCJ-9jrYxJA)在仔细看一下,然后再看这里的总结,相信会豁然开朗。
161+
162+
这里我尽量把逻辑的每一个细节都抠出来展现了,希望对大家有所帮助!
163+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp