给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]示例 2:
输入:root = [1]
输出:["1"]提示:
- 树中节点的数目在范围
[1, 100]内 -100 <= Node.val <= 100
解题思路:前序遍历
这道题并不难,无非就是遍历所有的从根节点到叶子节点的路径,只不过我们要将路径中的节点记录下来,所以我们可以考虑使用一个全局变量 ret 来记录每个从根节点到叶子节点的路径,然后用 path 变量来作为局部变量进行传参,方便回溯的时候自动“恢复现场”!
这里的回溯时候自动“恢复现场”的意思,其实就是因为当我们遍历完一条路径之后,我们肯定需要返回到上一层节点,继续看看它的右孩子还是继续返回上一层看看是否存在其它路径,那么此时 path 变量中记录的路径在返回的时候就得退回到原来的样子,为了方便,我们直接将其作为局部变量来传参,那么每一层调用的 path 变量其实都是独立的,就节省了回溯时候“恢复现场”的功夫,也就是如果设为全局变量的话,还得我们控制 path 当前该层的元素弹出,这就比较麻烦!
其它的没有什么好说的,因为要先处理当前节点,所以就是一个前序遍历!然后函数头的话,按照上面的说法,就是下面这样子:
// path表示当前的路径情况,为局部变量,方便回溯的时候自动“恢复现场”
// ret表示路径结果集,为引用,这样子起到全局变量的作用
void dfs(TreeNode* root, string path, vector<string>& ret); 剩下的也比较简单,就是当叶子节点的时候我们就处理一下 ret,将 path 以及当前叶子节点的路径字符串添加到 ret 中即可!如果不是叶子节点的话,则将当前节点添加到 path 中,继续往下递归左右子树即可!
完整代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> ret;
dfs(root, "", ret);
return ret;
}
// path为局部变量,方便回溯的时候自动“恢复现场”
// ret为引用,这样子起到全局变量的作用
void dfs(TreeNode* root, string path, vector<string>& ret)
{
// 函数递归出口
if(root->left == nullptr && root->right == nullptr)
{
ret.push_back(path + to_string(root->val));
return;
}
// 前序遍历,先处理当前节点
path += to_string(root->val) + "->";
// 再递归左右子树
if(root->left)
dfs(root->left, path, ret);
if(root->right)
dfs(root->right, path, ret);
}
};