(刷题笔记)Leetcode 257.二叉树的所有路径

这篇博客详细介绍了如何解决LeetCode中的257题——二叉树的所有路径。通过中序遍历的方法,利用栈记录节点和路径,实现了从根节点到叶子节点的所有路径的获取。文中还总结了二叉树遍历的四种方式,并讲解了C++中pair的使用技巧。最后给出了递归版本的解题代码,采用深度优先搜索策略。

题目

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

     1
   /   \ 
  2     3
   \
    5

输出: [“1->2->5”, “1->3”]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-paths

解题思路

这道题本质上是二叉树的中序遍历,只是需要一边遍历一边记录路径。
所以可以维护一个栈,记录中序遍历的结点和访问该结点经过的路径。
1.申请一个可以记录TreeNode和string的栈,一个指向root的临时变量temp
2.当栈非空或者temp不指向NULL时进行以下操作

  • 当temp不指向NULL时
+ a.判断temp是否与root相等,若相等则说明是路径开头,此处str=to_string(temp->val)
    若不相等,说明不是路径开头,str=str+“->”+to_string(temp->val) 
+ b.将temp和str存在栈中
+ c.继续向左遍历,temp=temp->left
  • 当temp指向NULL后
+ a.给temp和str重新赋值,为栈顶元素
+ b.判断temp的左右结点是否为NULL,若是,则找到一条路径,将str存入结果vector中,若不是,不进行操作。
+ c.继续向右遍历,temp=temp->right

3.跳出2的循环之后返回结果vector

知识点总结

  • 二叉树的遍历

    • 前序遍历:先访问根结点,然后遍历左子树,最后遍历右子树。
    • 中序遍历:先遍历左子树,然后访问根结点,最后遍历右子树。
    • 后序遍历:先遍历左子树,然后遍历右子树,最后访问根结点。
    • 层序遍历:从根结点从上往下逐层遍历,在同一层按从左往右的顺序逐个访问结点。
      参考:二叉树的四种遍历方式
  • pair的用法

    • 功能:将一对值(可能是不同类型)结合在一起(T1 和 T2)。可以通过其公共成员访问各个值first和second。
    • pair类型定义在#include 头文件中
    • 创建和初始化
      • 创建:在创建pair对象时,必须提供两个类型名,两个对应的类型名的类型不必相同。例pair<string, int> word_count;
      • 初始化:pair<string, int> name_age(“Tom”, 18); pair<string, int> name_age2(name_age);

代码(C++)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {

        vector<string>  vec;
        stack<pair<TreeNode*,string>> st;
        TreeNode* temp=root;
        string str;
        while(!st.empty()||temp){

            while(temp){
                if(temp==root){
                    str=str+to_string(temp->val);
                }
                else{
                    
                    str=str+"->"+to_string(temp->val);
                }
                st.push(pair<TreeNode*,string>(temp,str));
                temp=temp->left;
            }
            temp=st.top().first;
            str=st.top().second;
            st.pop();
            if(temp->right==NULL&&temp->left==NULL){
                vec.push_back(str);
            }
            temp=temp->right;
             
        }

        return vec;

    }
};

递归版本

递归版本的思想是深度优先搜索,需要注意的是引用传值的应用。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    void dfs(TreeNode* root,string path,vector<string> &res){
        
        if(root==NULL) return;
        path=path+to_string(root->val);
        if(root->left==NULL&&root->right==NULL){
            res.push_back(path);
        }
        else{
            path+="->";
        }
        dfs(root->left,path,res);
        dfs(root->right,path,res);
    }
    vector<string> binaryTreePaths(TreeNode* root) {

        vector<string> res;
        string path;
        dfs(root,path,res);
        return res;

       
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值