【算法与数据结构】112、LeetCode路径总和

news2024/11/22 16:52:49

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述
在这里插入图片描述

二、解法

  思路分析:本题通过计算根节点到叶子节点路径上节点的值之和,然后再对比目标值。利用文章【算法和数据结构】257、LeetCode二叉树的所有路径中的递归算法。这里要注意,默认路径之和是不等于目标值,一旦递归当中出现了等于的情况就直接返回,不必继续算后面的和。因此程序当中将结果result作为引用输入参数,有true出现就直接退出了。
  程序如下

class Solution {
public:          
    void traversal(TreeNode* root, int sumOfPath, const int targetSum, bool &result) {
        // 1.输入参数和返回值 
        sumOfPath += root->val;

        // 2.终止条件:遇到叶子节点
        if (!root->left && !root->right) {
            if (sumOfPath == targetSum) result = true;
        }

        // 3.单层递归逻辑:递归+回溯
        if (root->left && !result)  traversal(root->left, sumOfPath, targetSum, result);    // 左                         
        if (root->right && !result) traversal(root->right, sumOfPath, targetSum, result);  // 右
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        bool result = false;
        if(root) traversal(root, 0, targetSum, result);
        return result;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

三、完整代码

# include <iostream>
# include <vector>
# include <queue>
# include <string>
# include <algorithm>
# include <stack>
using namespace std;

// 树节点定义
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* root, int sumOfPath, const int targetSum, bool &result) {
        // 1.输入参数和返回值 
        sumOfPath += root->val;

        // 2.终止条件:遇到叶子节点
        if (!root->left && !root->right) {
            if (sumOfPath == targetSum) result = true;
        }

        // 3.单层递归逻辑:递归+回溯
        if (root->left && !result)  traversal(root->left, sumOfPath, targetSum, result);    // 左                         
        if (root->right && !result) traversal(root->right, sumOfPath, targetSum, result);  // 右
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        bool result = false;
        if(root) traversal(root, 0, targetSum, result);
        return result;
    }
};

template<typename T>
void my_print(T& v, const string msg)
{
    cout << msg << endl;
    for (class T::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << ' ';
    }
    cout << endl;
}

template<class T1, class T2>
void my_print2(T1& v, const string str) {
    cout << str << endl;
    for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {
        for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {
            cout << *it << ' ';
        }
        cout << endl;
    }
}

// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {
    if (!t.size() || t[0] == "NULL") return;    // 退出条件
    else {
        node = new TreeNode(stoi(t[0].c_str()));    // 中
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->left);              // 左
        }
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->right);             // 右
        }
    }
}

// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> que;
    if (root != NULL) que.push(root);
    vector<vector<int>> result;
    while (!que.empty()) {
        int size = que.size();  // size必须固定, que.size()是不断变化的
        vector<int> vec;
        for (int i = 0; i < size; ++i) {
            TreeNode* node = que.front();
            que.pop();
            vec.push_back(node->val);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
        result.push_back(vec);
    }
    return result;
}

// 二叉树所有路径
class Solution2 {
public:
    // 前序遍历递归法:精简版本      
    void traversal(TreeNode* root, string path, vector<string>& result) { // 1.输入参数和返回值        
        path += to_string(root->val);      // 中间节点先加入path
        if (!root->left && !root->right) {  // 2.终止条件:遇到叶子节点
            result.push_back(path);
            return;
        }
        // 3.单层递归逻辑:递归+回溯
        if (root->left) traversal(root->left, path + "->", result);     // 左
        if (root->right) traversal(root->right, path + "->", result);   // 右
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        if (!root) return result;
        traversal(root, "", result);
        return result;
    }
};

int main()
{
    vector<string> t = { "5", "4", "11", "7", "NULL", "NULL", "2", "NULL", "NULL", "NULL", "8", "13", "NULL", "NULL", "4", "NULL", "1", "NULL", "NULL"};   // 前序遍历
    my_print(t, "目标树");
    TreeNode* root = new TreeNode();
    Tree_Generator(t, root);
    vector<vector<int>> tree = levelOrder(root);
    my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");

    Solution2 s2;
    vector<string> path = s2.binaryTreePaths(root);
    my_print(path, "所有路径为:");

    Solution s;
    int targetSum = 22;
    bool result = s.hasPathSum(root, targetSum);
    cout << "路径总和是否满足目标值:  " << result << endl;
    system("pause");
    return 0;
}

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅析Redis(1)

一.Redis的含义 Redis可以用来作数据库&#xff0c;缓存&#xff0c;流引擎&#xff0c;消息队列。redis只有在分布式系统中才能充分的发挥作用&#xff0c;如果是单机程序&#xff0c;直接通过变量来存储数据是更优的选择。那我们知道进程之间是有隔离性的&#xff0c;那么re…

Android屏幕适配(5) — 最小宽度smallWidth适配

概述 最小宽度smallWidth适配实现屏幕适配方案 详细 前言 在之前的文章中&#xff0c;我们讲到了Android屏幕适配的一些知识&#xff0c;大家感兴趣的话可参考Android屏幕适配(1) — 概念解释Android屏幕适配(2) — drawable与mipmapAndroid屏幕适配(3) — 资源文件夹命名与…

音频母带制作::AAMS V4.0 Crack

自动音频母带制作简介。 使用 AAMS V4 让您的音乐听起来很美妙&#xff01; 作为从事音乐工作的音乐家&#xff0c;您在向公众发布材料时需要尽可能最好的声音&#xff0c;而为所有音频扬声器系统提供良好的商业声音是一项困难且耗时的任务。AI掌握的力量&#xff01; 掌控您…

网易新财报:游戏稳、有道进、云音乐正爬坡

今年以来&#xff0c;AI大模型的火热程度屡屡攀升&#xff0c;越来越多的企业都加入到了AI大模型的赛场中&#xff0c;纷纷下场布局。而在众多参与者中&#xff0c;互联网企业的身影更是频频浮现&#xff0c;比如&#xff0c;百度、阿里巴巴、腾讯等等。值得一提的是&#xff0…

mysql 存储引擎系列 (二) Innodb 存储引擎 和 myisam 存储引擎

InnoDB 引擎 支持外键InnoDB是MySQL默认事务型引擎&#xff0c;它被设计用来处理大量的短期事务。可以确保事务的完整提交&#xff08;commit&#xff09;和回滚&#xff08;Rollback&#xff09;增加和查询&#xff0c;且数据量少的&#xff0c;MyIsam 高效&#xff0c; 除了…

ps beta 2.5的妙用

1、https://pan.baidu.com/s/1CCw6RGlzEJ7TPWou8pPADQ?pwd2023 2、下载新便携版。 3、解压到c:\myapp文件夹下。 4、运行。 5、登录us账号。 6、使用智能移除。 效果如下&#xff1a; 使用滤镜。 先将C:\myApp\&#xff08;新便携版&#xff09;Adobe Photoshop (25.0.0 m22…

香橙派OrangePi zero H2+ 驱动移远4G/5G模块

目录 1 安装系统和内核文件&#xff1a; 1.1 下载镜像 1.2 内核头安装 1.2.1 下载内核 1.2.2 将内核头文件导入开发板中 1.2.3 安装内核头 2 安装依赖工具&#xff1a; 2.1 Installing Required Host Utilities 3 驱动步骤&#xff1a; 3.1 下载模块驱动文件…

微信小程序云开发案列

基础知识&#xff1a; async 微信小程序中 methods里面使用async 微信小程序中可以在methods里面使用async关键字来定义异步函数。例如&#xff1a; Page({data: {name: Tom,},async onLoad() {const res await wx.request({url: https://api.example.com/users,method: GE…

6、css学习6(表格)

1、指定CSS表格边框&#xff0c;使用border属性。 2、表格双边框是因为th/td有各自独立的边框。 3、boder-collapse设置表格边框是否被折叠成一个单一的边框。 4、width和height属性定义表格的宽度和高度。 5、text-align属性设置水平对齐方式。 6、vertic-align属性设置垂…

循环神经网络(RNN) | 项目还不成熟 |还在初级阶段

一&#xff0c;定义 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种深度学习神经网络架构&#xff0c;专门设计用于处理序列数据&#xff0c;如时间序列数据、自然语言文本等&#xff08;一般用来解决序列问题&#xff09;。 因为它们具…

YOLOv5、YOLOv8改进:CoordAtt注意力机制

目录 1.简介 2.Coordinate Attention 2.2 Coordinate Attention生成 3.YOLOv5改进 3.1common.py构建CoordAtt模块。 3.2 yolo.py中注册CoordAtt模块 3.3 yaml文件配置 1.简介 最近对移动网络设计的研究已经证明了通道注意力&#xff08;例如&#xff0c;Squeeze-an…

验证go循环删除slice,map的操作和map delete操作不会释放底层内存的问题

目录 切片 for 循环删除切片元素其他循环中删除slice元素的方法方法1方法2&#xff08;推荐&#xff09;方法3 官方提供的方法结论 切片 for 循环删除map元素goalng map delete操作不会释放底层内存 切片 for 循环删除切片元素 在 Go 语言中&#xff0c;使用 for 循环删除切片…

BookStack开源免费知识库docker-compose部署

BookStack&#xff08;书栈&#xff09;是一个功能强大且易于使用的开源知识管理平台&#xff0c;适用于个人、团队或企业的文档协作和知识共享。 一、BookStack特点 简单易用&#xff1a;BookStack提供了一个直观的用户界面&#xff0c;使用户能够轻松创建、编辑和组织文档多…

SpringBoot整合 redis key (过期、新增、修改)的三种方式,看这篇就够了

文章目录 原理关于 *notify-keyspace-events*关于redis的消息主题&#xff08;Topic&#xff09;重写监听容器注册自定义解析常见整合问题鸣谢 文章主要描述了Springboot整合key变化的三种方式&#xff0c;同时列出了一些整合坑点与概念 原理 SpringBoot整合Redis key变化的原…

二叉树的非递归遍历实现(三种)

1、先序遍历 先序遍历使用了栈的结构&#xff0c;先压入根节点&#xff0c;然后依次将其右子节点和左字节点压入。然后就可以实现“头左右”的遍历顺序 /*** 先序遍历*/public static void pre_order(TreeNode treeNode){if (treeNode null){return;}Stack<TreeNode> …

PAT 1136 A Delayed Palindrome

个人学习记录&#xff0c;代码难免不尽人意 A B C where A is the original number, B is the reversed A, and C is their sum. A starts being the input number, and this process ends until C becomes a palindromic number – in this case we print in the last line …

Graylog 更改显示的时区(Display timezone)

每个 Graylog 用户都可以配置他们的显示时区。 这会更改用于查看日志消息的时区&#xff0c;但不会更改日志消息的原始时区。 默认情况下&#xff0c;Graylog 显示 UTC 格式的所有时间戳&#xff08;也就是 0:00&#xff09;。就像是下面这样 非Admin账户要更改时区&#xff1…

防御网络攻击风险的4个步骤

如今&#xff0c;人们正在做大量工作来保护 IT 系统免受网络犯罪的侵害。令人担忧的是&#xff0c;对于运营技术系统来说&#xff0c;情况却并非如此&#xff0c;运营技术系统用于运行从工厂到石油管道再到发电厂的所有业务。 组织应该强化其网络安全策略&#xff0c;因为针对…

ConsoleApplication815项目(直接加载+VEH Hook Load)

上线图 ConsoleApplication815.cpp #include <iostream> #include<Windows.h> #include "detours.h" #include "detver.h" #pragma comment(lib,"detours.lib")#pragma warning(disable:4996)LPVOID Beacon_address; SIZE_T Beacon…

统计教程|PASS实现单因素多水平方差分析的样本含量估计

前面我们讲过当主要结局指标是连续变量时&#xff0c;两总体均数比较时样本量估计的计算公式原理以及PASS软件操作教程。当设计研究的试验因素只有一个&#xff0c;并且该因素的水平数&#xff08;组数&#xff09;k≥3&#xff0c;当主要研究指标为连续变量时我们常用单因素多…