【二叉树算法题记录】二叉树的所有路径,路径总和——回溯

目录

257. 二叉树的所有路径

题目描述

给你一个二叉树的根节点root ,按任意顺序,返回所有从根节点到叶子节点的路径。

题目分析

其实从根节点往下走,遍历的思路就如下图所示。我们先走到叶子节点(这是一条路径),然后再往上回溯 ,如果回溯到的上层节点有右孩子,那么就再按照右边的路径往下走(另一条路径)。

  1. 递归传入参数及返回值
cpp 复制代码
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)

cur是当前节点,path用来记录当前路径,result是最终返回的结果。

  1. 递归终止条件
    当我们遍历到叶子节点时,就要把当前路径path加入result了。
cpp 复制代码
if(cur->left == NULL && cur->right == NULL) {
            // 如果当前节点是叶子节点,也就是左右孩子都为空
            // 也就是说已经遍历了一条根节点到叶子节点的路径
            // 我们要把这条路径放进result中
            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;
        }
  1. 单层递归逻辑
    我们进行的是一个前序遍历,但是需要注意的是当前节点的处理要在递归终止条件之前进行:
cpp 复制代码
path.push_back(cur->val);   // 先将当前节点放进当前path中,再判断结束条件

这是因为所有节点包括叶子节点都要加入path,如果先判断终止,再处理当前节点则会漏掉叶子节点。

在进行左右孩子的遍历时,我们要注意判断节点是否为空:

cpp 复制代码
if(cur->left) {
            traversal(cur->left, path, result);
            path.pop_back();    // 回溯
        }
        if(cur->right) {
            traversal(cur->right, path, result);
            path.pop_back();    // 回溯
        }

cpp代码

cpp 复制代码
/**
 * 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 {
public:
    void traversal(TreeNode* cur, vector<int>& path, vector<string>& result){
        path.push_back(cur->val);   // 先将当前节点放进当前path中,再判断结束条件
        if(cur->left == NULL && cur->right == NULL) {
            // 如果当前节点是叶子节点,也就是左右孩子都为空
            // 也就是说已经遍历了一条根节点到叶子节点的路径
            // 我们要把这条路径放进result中
            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();    // 回溯
        }
        
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<int> path;
        vector<string> result;
        if(root == NULL) return result;
        traversal(root, path, result);
        return result;
    }
};

112. 路径总和

题目描述

给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false

题目分析

其实这题跟上题是一样的,只不过这里多了一个targetSum的判断。

cpp代码

cpp 复制代码
/**
 * 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 {
public:
    void traversal(TreeNode* cur, vector<int>& path, vector<int>& sum){
        path.push_back(cur->val);

        if(cur->left == NULL && cur->right == NULL) {

            cout << "当前路径: ";
            for(int p : path) {
                cout << p << ' ';
            }
            cout << endl;

            sum.push_back(accumulate(path.begin(), path.end(), 0));
            cout << "当前路径总和: " << accumulate(path.begin(), path.end(), 0) << endl;
            return;
        }

        if(cur->left) {
            traversal(cur->left, path, sum);
            path.pop_back();
        }
        if(cur->right) {
            traversal(cur->right, path, sum);
            path.pop_back();
        }
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        vector<int> path;
        vector<int> sum;
        if(root == NULL) return false;
        traversal(root, path, sum);
        if(find(sum.begin(), sum.end(), targetSum) == sum.end()){
            return false;
        }
        else return true;
    }
};
相关推荐
逻辑驱动的ken21 分钟前
Java高频面试考点场景题09
java·开发语言·数据库·算法·oracle·哈希算法·散列表
帅小伙―苏35 分钟前
力扣42接雨水
前端·算法·leetcode
AI科技星1 小时前
精细结构常数α的几何本源:从第一性原理的求导证明、量纲分析与全域验证
算法·机器学习·数学建模·数据挖掘·量子计算
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
c++·算法·leetcode
MegaDataFlowers1 小时前
26.删除有序数组中的重复项
算法
码完就睡2 小时前
数据结构——栈和队列的相互模拟
数据结构
iiiiyu2 小时前
常用API(SimpleDateFormat类 & Calendar类 & JDK8日期 时间 日期时间 & JDK8日期(时区) )
java·大数据·开发语言·数据结构·编程语言
故事和你912 小时前
洛谷-数据结构1-4-图的基本应用2
开发语言·数据结构·算法·深度优先·动态规划·图论
吴可可1233 小时前
C#合并首尾相连多段线实战
算法·c#
KMDxiaozuanfeng3 小时前
卡梅德生物技术快报|SPR 技术应用|基于 SPR 亲和力的中药活性成分筛选系统实现与数据分析
科技·算法·面试·考试