题目:
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点
/**
* 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 {
// /********************法一::递归法************************/
// private:
// void travelsal(TreeNode* cur, vector<int>& path, vector<string>& result)
// {
// // 应该是要用前序遍历
// path.push_back(cur->val);
// // 上一句是对根节点的处理,完事儿之后才轮到叶子节点,
// // 这里的终止条件是针对叶子节点,因此才把顺序这么排
// if(cur->left == nullptr && cur->right == nullptr)
// {
// // 这里是为了把 path 转为string类型
// string sPath;
// // 这里注意 i 的终止条件,是为了把path中的最后一个元素留下来最后操作,
// // 因为最后一个元素不需要 “->” 这个符号
// for(int i=0; i<path.size()-1; i++)
// {
// sPath += to_string(path[i]);
// sPath += "->";
// }
// sPath += to_string(path[path.size()-1]);
// result.push_back(sPath);
// return;
// }
// // 在叶子节点处 写递归的逻辑和回溯
// if(cur->left)
// {
// travelsal(cur->left,path,result);
// path.pop_back(); // 这一步是回溯,递归紧挨着回溯
// }
// if(cur->right)
// {
// travelsal(cur->right,path,result);
// path.pop_back(); // 这一步是回溯,递归紧挨着回溯
// }
// }
// /********************法二::精简版递归法************************/
// private:
// // 这里参数传递,result还是用引用,
// // 但是path是传值,否则无法做到回溯的效果,
// // 传值的话,就相当于处理完下一层,还能还是返回了本层
// void travelsal(TreeNode* cur, string path, vector<string>& result)
// {
// path += to_string(cur->val);
// if(cur->left == nullptr && cur->right == nullptr)
// {
// result.push_back(path);
// return;
// }
// if(cur->left)
// {
// travelsal(cur->left, path + "->", result);
// }
// if(cur->right)
// {
// travelsal(cur->right, path + "->", result);
// }
// }
// public:
// vector<string> binaryTreePaths(TreeNode* root)
// {
// // 第一种递归
// // vector<int> path;
// // 第二种递归
// string path;
// vector<string> result;
// if(root == nullptr)
// {
// return result;
// }
// travelsal(root,path,result);
// return result;
// }
/********************法三::迭代法************************/
public:
// 定义两个栈:
// 一个栈用来存储树的节点,用前序遍历
// 一个栈用来存储遍历路径的节点,
vector<string> binaryTreePaths(TreeNode* root)
{
stack<TreeNode*> treeSt; // 保存树的遍历节点
stack<string> pathSt; // 保存遍历路径的节点
vector<string> result; // 保存最终路径集合
if(root == nullptr) return result;
treeSt.push(root);
pathSt.push(to_string(root->val));
while(!treeSt.empty())
{
// 这儿没用统一的迭代法,是借用 中左右的特殊性
// 先处理 中节点
// 然后把 右节点 和 左节点 依次压栈
// 接下来这四步相当于是对 中节点 操作
TreeNode* node = treeSt.top();
treeSt.pop(); // 对 节点 的操作
string path = pathSt.top();
pathSt.pop(); // 对 该节点路径 的操作
// 注意这里的判断条件也要变,因为要在遇到叶子节点时才这么操作
if(node->left == nullptr && node->right == nullptr)
{
result.push_back(path);
}
// 接下来处理 右节点
if(node->right != nullptr)
{
treeSt.push(node->right);
// 路径的保存工作就在这里做了
pathSt.push(path + "->" + to_string(node->right->val));
}
// 接下来处理 左节点
if(node->left != nullptr)
{
treeSt.push(node->left);
pathSt.push(path + "->" + to_string(node->left->val));
}
}
return result;
}
};