LeetCode112. 路径总和

news2024/10/3 2:28:41

112. 路径总和

文章目录

      • [112. 路径总和](https://leetcode.cn/problems/path-sum/)
        • 一、题目
        • 二、题解
          • 方法一:递归存储各个路径之和
          • 方法二:递归版本2
          • 简化版本


一、题目

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

叶子节点 是指没有子节点的节点。

示例 1:

img

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:

img

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。

提示:

  • 树中节点的数目在范围 [0, 5000]
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000

二、题解

方法一:递归存储各个路径之和

我们可以采取一种深度优先搜索的递归方法来解决。

算法思路

  1. 我们可以从根节点开始,递归地向下搜索每条路径,计算路径上节点值的和。
  2. 当遇到叶子节点时,即没有左子节点和右子节点的节点,将当前路径的和加入结果数组中。
  3. 最后,遍历结果数组,检查是否存在与目标和相等的路径和。

具体实现

/**
 * 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 getSum(TreeNode* root, int sum, vector<int>& result){
        if(root == nullptr) return;
        int sum_r = sum + root->val;
        
        // 当前节点为叶子节点时,将路径和加入结果数组
        if(!root->left && !root->right){
            result.push_back(sum_r);
        }else{
            getSum(root->left, sum_r, result);
            getSum(root->right, sum_r, result);
        }
    }
    
    // 主函数,判断是否存在路径和等于目标和
    bool hasPathSum(TreeNode* root, int targetSum) {
        vector<int> result;
        getSum(root, 0, result);
        
        // 遍历结果数组,检查是否存在与目标和相等的路径和
        for(auto i: result){
            if(i == targetSum){
                return true;
            }
        }
        return false;
    }
};

算法分析

  • 时间复杂度:遍历整棵树的时间复杂度为 O(n),其中 n 是树中节点的数量。这是因为我们需要访问每个节点一次以计算路径和。对结果数组进行遍历的时间复杂度是 O(n)。
  • 空间复杂度:在递归过程中,我们需要存储每条路径的和,因此递归调用的最大深度不会超过树的高度,即 O(h),其中 h 是树的高度。在存储结果数组时,最坏情况下需要 O(n) 的空间。
方法二:递归版本2

这个版本不需要数组的存储

算法思路

  1. 我们定义一个递归函数 traversal,该函数接受三个参数:当前节点 cur,当前路径的和 count,和目标和 target
  2. traversal 函数中,首先判断当前节点是否为叶子节点,如果是叶子节点并且路径和等于目标和,则返回 true,否则返回 false
  3. 如果当前节点不是叶子节点,则尝试向左子树和右子树递归,分别计算新的路径和,然后将两次递归的结果进行逻辑或运算,最终返回。

具体实现

class Solution {
public:
    bool traversal(TreeNode *cur, int count, int target){
        // 到达叶子节点时判断路径和是否等于目标和
        if (count == target && !cur->left && !cur->right) {
            return true;
        }
        
        // 到达叶子节点但路径和不等于目标和
        if (!cur->left && !cur->right) {
            return false;
        }
        
        bool left_b = false;
        bool right_b = false;
        // 递归搜索左子树
        if (cur->left) {
            left_b = traversal(cur->left, count + cur->left->val, target);
        }
        // 递归搜索右子树
        if (cur->right) {
            right_b = traversal(cur->right, count + cur->right->val, target);
        }
        
        // 返回左子树和右子树递归的结果的逻辑或
        return (left_b || right_b);
    }
    
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) {
            return false;
        }
        return traversal(root, root->val, targetSum);
    }
};

算法分析

  • 时间复杂度:遍历整棵树的时间复杂度为 O(n),其中 n 是树中节点的数量。每个节点最多被访问一次。
  • 空间复杂度:递归调用的最大深度不会超过树的高度,即 O(h),其中 h 是树的高度。在递归过程中,只使用了常数级别的额外空间。
简化版本
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) {
            return false;
        }
        
        if (!root->left && !root->right) {
            return root->val == targetSum;
        }
        
        int remainingSum = targetSum - root->val;
        return hasPathSum(root->left, remainingSum) || hasPathSum(root->right, remainingSum);
    }
};

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

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

相关文章

回调函数的简单用例

列举项目中一个简单的回调函数用例 ①用MsgInterface_t定义一个结构体s_Lin_MsgInterface&#xff0c;包含两个回调函数成员&#xff1a; ②确定结构体下的回调函数成员的参数&#xff1a; ③传入实参&#xff0c;确定结构体下的回调函数成员的函数名&#xff1a; ④最终回…

docker容器互联详解

目录 docker容器互联详解 一、容器互联概述&#xff1a; 二、案例实验&#xff1a; 1、用户自定义的网络&#xff1a; 2、查看当前的IP信息&#xff1a; 3、启动第三个容器&#xff1a; 4、查看三个容器内部的网络&#xff1a; 5、Ping测试&#xff1a; Ps备注&#x…

CVE-2008-5161

SSH服务器CBC加密模式漏洞 1.描述 一般经过我们的加固&#xff0c;Linux环境中一般都已经采用AES这种算法加密&#xff0c;AES有五种加密模式&#xff08;CBC、ECB、CTR、OCF、CFB&#xff09;&#xff0c;centos7.x系统启动sshd服务后&#xff0c;系统默认选择CBC的机密模式…

div上下左右居中几种方式

div固定宽高 div{width:200px;height:200px;background-color:red; }1、绝对定位&#xff08;常用于登录模块&#xff09; 备注&#xff1a;前提条件div需要有宽高 #html <div class"box"></div> #css .box{ position:absolute/fixed; left:0; right:0…

凯迪正大—SF6泄漏报警装置的主要特点

SF6泄漏报警系统主要特点 ① 系统采用声速原理&#xff0c;可定量、实时在线测量SF6泄漏气体含量&#xff0c;克服了传统测量方法如负电晕放电法和卤素传感器法只能定性判别是否越限的缺陷&#xff0c;能够准确得到气体中SF6含量。 ② 系统采用双差分处理方法&#xff0c;有效…

Linux知识点 -- 进程间通信(一)

Linux知识点 – 进程间通信&#xff08;一&#xff09; 文章目录 Linux知识点 -- 进程间通信&#xff08;一&#xff09;一、了解进程间通信1.进程间通信的必要性2.进程间通信的技术背景3.进程间通信的本质理解4.进程间通信的标准 二、匿名管道1.匿名管道通信的原理2.匿名管道的…

Docker网络模型详解

目录 一、Docker网络基础 1.1、端口映射 1.2、端口暴露 1.3、容器互联 二、Docker网络模式 2.1、Host模式 2.2、container模式 2.3、none模式 2.4、bridge模式 2.5、Overlay模式 网络是激活Docker体系的唯一途径&#xff0c;如果Docker没有比较出色的容器网络&#xff0…

SpringBoot项目-个人博客系统的实现【下】

10.实现强制要求登陆 当用户访问 博客列表页和 博客详情页时, 如果用户当前尚未登陆, 就自动跳转到登陆页面 1.添加拦截器 public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletRespon…

程序员私活渠道揭,探索项目接单秘

对于程序员来说&#xff0c;接私活是很正常的事情&#xff0c;在工作闲暇时间利用业余时间来赚点零花钱还是非常不错的&#xff0c;但是如果能一边接私活一边提高自己的水平那就更好了。 这里给大家的建议就是&#xff0c;可以接一些稍微有难度但是在自己能力范围的项目&#x…

自动化测试:封装入口文件

1自动生成测试报告&#xff0c;start_dir是要找入口文件的相对目录。测试用例有规律的话&#xff0c;pattern可以批量执行&#xff08;通过相同的开头*&#xff09; start_dir 是要执行的测试文件所在的目录&#xff0c;pattern可以理解为具体的执行测试的文件 2所有的底层操…

C++stack_queue

stack_queue 容器适配器stack详解栈适配器栈模拟实现 队列详解队列适配器queue模拟实现 容器适配器 除了顺序容器外&#xff0c;标准库还定义了三个顺序容器适配器:stack(栈),queue(队列),priority_queue(优先队列)。适配器是标准库中的一个通用概念。容器&#xff0c;迭代器和…

Android Jetpack

Jetpack 是一个由多个库组成的套件&#xff0c;可帮助开发者遵循最佳实践、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码&#xff0c;让开发者可将精力集中于真正重要的编码工作。 1.基础组件 &#xff08;1&#xff09;AppCompat&#xff1a;使得支持较低…

了解政策法规和行业规范,可以帮助写作人员更好地理解公文要求和标准

了解政策法规和行业规范&#xff0c;可以帮助写作人员更好地理解公文要求和标准。 政策法规和行业规范是公文写作的重要参考依据&#xff0c;包括相关法律法规、行业标准和制度规定等。了解这些规范和标准可以帮助写作人员更好地掌握公文的表达要求和规范要求&#xff0c;以确保…

跨境选品怎么选?建议独立站卖家收下这份利基产品查找攻略!

跨境电商平台现在可谓是火热发展中&#xff0c;独立站出海风口&#xff0c;其实选择的机会还真不少&#xff0c;相比国内电商的发展势头&#xff0c;看得出来&#xff0c;未来跨境电商的大门&#xff0c;对你而言&#xff0c;敞开着。选品这事儿&#xff0c;就像你上战场前挑选…

linux_驱动_iic总线获取si7006温湿度

应用层si7006.c #include<stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <arpa/inet.h>…

学生信息管理系统springboot学校学籍专业数据java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 学生信息管理系统springboot 系统3权限&#xff1a;超…

C语言 函数指针详解

一、函数指针 1.1、概念 函数指针&#xff1a;首先它是一个指针&#xff0c;一个指向函数的指针&#xff0c;在内存空间中存放的是函数的地址&#xff1b; 示例&#xff1a; int Add(int x&#xff0c;int y) {return xy;} int main() {printf("%p\n",&Add);…

Linux tcpdump 命令详解

简介 用简单的话来定义tcpdump&#xff0c;就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的…

MPLS(下)

LDP --- 标签分发协议 --- 主要应用在MPLS的控制层面 MPLS控制层面需要完成的工作主要就是分配标签和传递标签。分配标签的前提是本地路由表中得先存在标签&#xff0c;传递标签的前提也是得先具备路由基础。所以&#xff0c;LDP想要正常工作&#xff0c;则需要IGP作为基础。 …

Docker实战-操作Docker容器实战(一)

导语   在之前的分享中&#xff0c;我们介绍了关于如何去操作Docker镜像&#xff0c;下面我们来看看如何去操作容器。 简单来讲&#xff0c;容器是镜像运行的一个实例&#xff0c;与镜像不同的是镜像只能作为一个静态文件进行读取&#xff0c;而容器是可以在运行时进行写入操…