leetcode——第257——二叉树的所有路径--第一个回溯的写法--好难啊看了半天

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

/**
 * 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值