本题的重要思想是回溯,每次记录完当前路径都需要返回上一节点寻找下一路径,因此需要用数组记录当前遍历过的节点,进行回溯操作。同时本题要求记录根节点到叶子结点的路径,因此使用前序遍历容易找到相应的路径。
在每次进行递归时,
(1)需要判断当前节点是否为叶子结点,若节点的左右孩子都为空,则当前节点是叶子结点,需要对当前数组所保存的路径进行记录
(2)若节点的左孩子存在,则对节点的左孩子进行下一步递归,同时进行回溯操作,将数组内的最后一个节点弹出
(3)若节点的右孩子存在,则对节点的右孩子进行下一步递归,同时进行回溯操作,将数组内的最后一个节点弹出
如此,便记录了根节点到所有叶子结点的路径,代码如下:
// 版本一
class Solution {
private:
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中
// 这才到了叶子节点
if (cur->left == NULL && cur->right == NULL) {
string sPath;
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) { // 左
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) { // 右
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
};