题目

257 二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。

示例
输入:root = [1,2,3,null,5]
输出:[“1->2->5”,”1->3”]

思路

本题用到了回溯的思想。

本题要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。而且我们要把路径记录下来,当一个路径在进入另一个路径时需要回溯来回退
本题需要如下的递归函数

  1. 递归定义:void getTreePaths(TreeNode* cur, vector<int>& path, vector<string>& result)
    • 输入node, 返回记录的路径和结果vector
  2. 递归终止条件
    • node为空,直接返回
    • node左右子节点为空, 根据当前节点和path生成string,添加到result中,返回
  3. 不符合递归终止条件,则添加当前节点值到path,继续递归

再看回溯,回溯和递归是一一对应的,有一个递归,就要有一个回溯,所以在每次递归返回后,都要进行回溯。
本题中递归只会把当前节点添加到path中,回溯意味着把当前节点从path中删除,不然下次进入递归时path中会存在错误的节点值。

  1. class Solution
  2. {
  3. public:
  4. vector<string> binaryTreePaths(TreeNode *root)
  5. {
  6. if (root == nullptr)
  7. return {};
  8. vector<int> path; //记录一条路径, 用于回溯
  9. vector<string> vec;
  10. getTreePaths(root, path, vec);
  11. return vec;
  12. }
  13. private:
  14. void getTreePaths(TreeNode *cur, vector<int> &path, vector<string> &result)
  15. {
  16. if (cur == nullptr) //终止条件1
  17. return;
  18. //添加当前节点到path
  19. path.push_back(cur->val);
  20. //判断是否符合递归终止条件2
  21. if (cur->left == nullptr && cur->right == nullptr)
  22. {
  23. string tmp;
  24. for (auto p : path)
  25. {
  26. tmp += std::to_string(p) + "->";
  27. }
  28. tmp.resize(tmp.size() - 2); //去除末尾->
  29. result.push_back(tmp);
  30. return;
  31. }
  32. if (cur->left != nullptr)
  33. {
  34. //递归左子节点
  35. getTreePaths(cur->left, path, result);
  36. //回溯
  37. path.pop_back(); //这里把左子节点移除
  38. }
  39. if (cur->right != nullptr)
  40. {
  41. //递归右子节点
  42. getTreePaths(cur->right, path, result);
  43. //回溯
  44. path.pop_back(); //这里把右子节点移除
  45. }
  46. return;
  47. }
  48. };