mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 08:50:15 +08:00
update 0257.二叉树的所有路径: 优化 js 代码格式和错字
This commit is contained in:
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
|
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
|
||||||
|
|
||||||
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一一个路径在进入另一个路径。
|
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
|
||||||
|
|
||||||
前序遍历以及回溯的过程如图:
|
前序遍历以及回溯的过程如图:
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)
|
|||||||
|
|
||||||
2. 确定递归终止条件
|
2. 确定递归终止条件
|
||||||
|
|
||||||
再写递归的时候都习惯了这么写:
|
在写递归的时候都习惯了这么写:
|
||||||
|
|
||||||
```
|
```
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
@ -67,7 +67,7 @@ if (cur->left == NULL && cur->right == NULL) {
|
|||||||
|
|
||||||
再来看一下终止处理的逻辑。
|
再来看一下终止处理的逻辑。
|
||||||
|
|
||||||
这里使用vector<int> 结构path来记录路径,所以要把vector<int> 结构的path转为string格式,在把这个string 放进 result里。
|
这里使用vector<int> 结构path来记录路径,所以要把vector<int> 结构的path转为string格式,再把这个string 放进 result里。
|
||||||
|
|
||||||
**那么为什么使用了vector<int> 结构来记录路径呢?** 因为在下面处理单层递归逻辑的时候,要做回溯,使用vector方便来做回溯。
|
**那么为什么使用了vector<int> 结构来记录路径呢?** 因为在下面处理单层递归逻辑的时候,要做回溯,使用vector方便来做回溯。
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ if (cur->right) {
|
|||||||
path.pop_back();
|
path.pop_back();
|
||||||
```
|
```
|
||||||
|
|
||||||
这个回溯就要很大的问题,我们知道,**回溯和递归是一一对应的,有一个递归,就要有一个回溯**,这么写的话相当于把递归和回溯拆开了, 一个在花括号里,一个在花括号外。
|
这个回溯就有很大的问题,我们知道,**回溯和递归是一一对应的,有一个递归,就要有一个回溯**,这么写的话相当于把递归和回溯拆开了, 一个在花括号里,一个在花括号外。
|
||||||
|
|
||||||
**所以回溯要和递归永远在一起,世界上最遥远的距离是你在花括号里,而我在花括号外!**
|
**所以回溯要和递归永远在一起,世界上最遥远的距离是你在花括号里,而我在花括号外!**
|
||||||
|
|
||||||
@ -300,16 +300,16 @@ public:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**大家应该可以感受出来,如果把 `path + "->"`作为函数参数就是可以的,因为并有没有改变path的数值,执行完递归函数之后,path依然是之前的数值(相当于回溯了)**
|
**大家应该可以感受出来,如果把 `path + "->"`作为函数参数就是可以的,因为并没有改变path的数值,执行完递归函数之后,path依然是之前的数值(相当于回溯了)**
|
||||||
|
|
||||||
|
|
||||||
**综合以上,第二种递归的代码虽然精简但把很多重要的点隐藏在了代码细节里,第一种递归写法虽然代码多一些,但是把每一个逻辑处理都完整的展现了出来了。**
|
**综合以上,第二种递归的代码虽然精简但把很多重要的点隐藏在了代码细节里,第一种递归写法虽然代码多一些,但是把每一个逻辑处理都完整的展现出来了。**
|
||||||
|
|
||||||
## 拓展
|
## 拓展
|
||||||
|
|
||||||
这里讲解本题解的写法逻辑以及一些更具体的细节,下面的讲解中,涉及到C++语法特性,如果不是C++的录友,就可以不看了,避免越看越晕。
|
这里讲解本题解的写法逻辑以及一些更具体的细节,下面的讲解中,涉及到C++语法特性,如果不是C++的录友,就可以不看了,避免越看越晕。
|
||||||
|
|
||||||
如果是C++的录友,建议本题独立刷过两遍,在看下面的讲解,同样避免越看越晕,造成不必要的负担。
|
如果是C++的录友,建议本题独立刷过两遍,再看下面的讲解,同样避免越看越晕,造成不必要的负担。
|
||||||
|
|
||||||
在第二版本的代码中,其实仅仅是回溯了 `->` 部分(调用两次pop_back,一个pop`>` 一次pop`-`),大家应该疑惑那么 `path += to_string(cur->val);` 这一步为什么没有回溯呢? 一条路径能持续加节点 不做回溯吗?
|
在第二版本的代码中,其实仅仅是回溯了 `->` 部分(调用两次pop_back,一个pop`>` 一次pop`-`),大家应该疑惑那么 `path += to_string(cur->val);` 这一步为什么没有回溯呢? 一条路径能持续加节点 不做回溯吗?
|
||||||
|
|
||||||
@ -378,7 +378,7 @@ public:
|
|||||||
|
|
||||||
最后我依然给出了迭代法。
|
最后我依然给出了迭代法。
|
||||||
|
|
||||||
对于本地充分了解递归与回溯的过程之后,有精力的同学可以在去实现迭代法。
|
对于本题充分了解递归与回溯的过程之后,有精力的同学可以再去实现迭代法。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ public:
|
|||||||
|
|
||||||
# 其他语言版本
|
# 其他语言版本
|
||||||
|
|
||||||
Java:
|
## Java:
|
||||||
|
|
||||||
```Java
|
```Java
|
||||||
//解法一
|
//解法一
|
||||||
@ -466,7 +466,7 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
Python:
|
## Python:
|
||||||
递归法+隐形回溯
|
递归法+隐形回溯
|
||||||
```Python3
|
```Python3
|
||||||
# Definition for a binary tree node.
|
# Definition for a binary tree node.
|
||||||
@ -529,7 +529,7 @@ class Solution:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Go:
|
## Go:
|
||||||
|
|
||||||
递归法:
|
递归法:
|
||||||
|
|
||||||
@ -591,28 +591,28 @@ func binaryTreePaths(root *TreeNode) []string {
|
|||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
JavaScript:
|
## JavaScript:
|
||||||
|
|
||||||
递归法:
|
递归法:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var binaryTreePaths = function(root) {
|
var binaryTreePaths = function(root) {
|
||||||
//递归遍历+递归三部曲
|
//递归遍历+递归三部曲
|
||||||
let res=[];
|
let res = [];
|
||||||
//1. 确定递归函数 函数参数
|
//1. 确定递归函数 函数参数
|
||||||
const getPath=function(node,curPath){
|
const getPath = function(node,curPath) {
|
||||||
//2. 确定终止条件,到叶子节点就终止
|
//2. 确定终止条件,到叶子节点就终止
|
||||||
if(node.left===null&&node.right===null){
|
if(node.left === null && node.right === null) {
|
||||||
curPath+=node.val;
|
curPath += node.val;
|
||||||
res.push(curPath);
|
res.push(curPath);
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
//3. 确定单层递归逻辑
|
//3. 确定单层递归逻辑
|
||||||
curPath+=node.val+'->';
|
curPath += node.val + '->';
|
||||||
node.left&&getPath(node.left,curPath);
|
node.left && getPath(node.left, curPath);
|
||||||
node.right&&getPath(node.right,curPath);
|
node.right && getPath(node.right, curPath);
|
||||||
}
|
}
|
||||||
getPath(root,'');
|
getPath(root, '');
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
@ -644,7 +644,7 @@ var binaryTreePaths = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
TypeScript:
|
## TypeScript:
|
||||||
|
|
||||||
> 递归法
|
> 递归法
|
||||||
|
|
||||||
@ -698,7 +698,7 @@ function binaryTreePaths(root: TreeNode | null): string[] {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Swift:
|
## Swift:
|
||||||
|
|
||||||
> 递归/回溯
|
> 递归/回溯
|
||||||
```swift
|
```swift
|
||||||
@ -765,7 +765,7 @@ func binaryTreePaths(_ root: TreeNode?) -> [String] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Scala:
|
## Scala:
|
||||||
|
|
||||||
递归:
|
递归:
|
||||||
```scala
|
```scala
|
||||||
|
Reference in New Issue
Block a user