算法:leetcode_112_路径总和

关于bfs(广度优先搜索算法)和dfs(深度优先搜索算法)--leetcode题:1036. 逃离大迷宫;112. 路径总和;113. 路径总和 II;102. 二叉树的层序遍历;200. 岛屿数量 leetcode 每日一题 1036. 逃离大迷宫 在一个 106 x 106 的网格中,每个网格上方格的坐标为 (x, y) 。 现在从源方格 source = [sx, sy] 开始出发,意图赶往目标方格 target = [tx, ty] 。数组 blocked 是封锁的方格列表,其中每个 blocked[i] = [xi, yi] 表示坐标为 (xi, yi) 的方格是禁止通行的。 每次移动,都可以走到网格中在四个方向上相邻的方格,只要该方格 不 在给出的封锁列表 blocked 上。同时,不允许走 阅读详情

目录

0. 前言

1. 题目介绍

2. 思路模拟

3. 结果演示[分享打印工具类]

4. 代码 

Java:

简洁版代码:

C++:

JS:

5. 更新预告:


0. 前言

这是一道面试高频题目, 也是一道回溯模板题, 

先贴出力扣链接:

112. 路径总和 - 力扣(LeetCode)

这道题和另一道回溯模板题非常像, 但是更容易错误点。

129. 求根节点到叶节点数字之和 - 力扣(LeetCode)

适合一起做了, 锻炼递归思想,相关笔记可以看看我的另一篇分享博客:算法:leetcode_129_求根节点到叶节点数字之和-优快云博客

1. 题目介绍

 注意:

  • 节点数可以为0
  • 节点值也可以为负

 

2. 思路模拟

一起跟着我的思路来吧:

我们刚开始的积分path是0

【为什么变量名字叫path->因为这是访问整条路径的全局变量, 关乎是否能结束游戏,

其他类似的回溯的题目, path通常是作为字符串,链表结构,作为统一就叫path吧。当然变量名字无所谓, 叫sum也行】

每访问完一个节点, 积分加上对应节点的值val :

path += root.val;

我们的积分要达到题目给定的22才能够通关, 同时我们已经尽力了: 到达了最深处【叶子节点】:

积分够了 但是还在路中央是不可以的嗷,必须到底!

if(path == target && root.left == null && root.right == null){
    return true;
}

这个节点访问完了, 但是游戏没结束, 把接下来的任务交给孩子们吧:

left和right代表从这个子节点进去, 最终是否能够完成任务, 不一定就是它本人完成了任务, 大概率是它孙子的孙子的孙子的孙子........... 最底层的叶子节点是否顺利完成了任务。

简洁来说, 以这个子节点为根节点重新开始游戏, 是否能成功。

boolean left = dfs(root.left);
boolean right = dfs(root.right);

我已经燃尽了, 准备把任务的结果汇报给上一级:

现在任务是否完成, 取决于孩子, 两个孩子其中有一个完成了任务也算我们胜利!

再提交任务之前, 先把当前已经有的积分给扣除(积分只留给有希望胜利的人), 已经遍历过的节点拿着也没用:

// 两个孩子都处理完了, 自己的任务也完成了, 返回上一层之前先交出它的值
path -= root.val;
// 两个孩子 有一个孩子顺利结束战斗 都算成功
return left || right;

当踩空了怎么办, 遇到了空节点, 直接返回!

判空只有两个地方能遇到,

  1. 访问这整棵树的根节点的时候, 根节点为空, 直接游戏失败;
  2. 访问完了叶子节点之后, 同时此时拥有的积分path不等于目标值targetSum, 还要遍历叶子节点的左右两个子节点, 但是两孩子都为空, 此时刚dfs进去, 游戏还没开始就结束了。
// 当节点为空 直接返回false
if(root == null) return false;

3. 结果演示[分享打印工具类]

你还在为构造树结构烦恼吗, leetcode那么多二叉树类型的题目, 传入参数都是TreeNode, 难道每次都要:

        // 慢慢构造树节点
        TreeNode node1 = new TreeNode(5);
        TreeNode node2 = new TreeNode(4);
        TreeNode node3 = new TreeNode(8);
        TreeNode node4 = new TreeNode(11);
        TreeNode node5 = new TreeNode(13);
        TreeNode node6 = new TreeNode(4);
        TreeNode node7 = new TreeNode(7);
        TreeNode node8 = new TreeNode(2);
        TreeNode node9 = new TreeNode(1);
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node3.left = node5;
        node3.right = node6;
        node4.left = node7;
        node4.right = node8;
        node6.right = node9;
        // 传入本题参数
        System.out.println(hasPathSum(root, 22));

为各位大懒猪们推荐我写的垃圾工具类, 可以轻松通过数组构造树或者链表结构

打印节点(链表或者二叉树)工具-优快云博客

其中的Constant.NULL赋值为Integer.MIN_VALUE, 作为二叉树中的空节点:

public static void main(String[] args) {
    // 1. 获取打印工具对象, 第二个参数为0代表链表工具, 为1代表二叉树工具
    PrintUtils utils = new PrintUtils(new int[]{5, 4, 8, 11, Constant.NULL, 13, 4, 7, 2, Constant.NULL, Constant.NULL, Constant.NULL, 1}, 1);
    // 2. 自动根据工具对象类型为链表还是二叉树, 打印出对应的结构到控制台
    utils.print();
    // 3. 获取二叉树结构对象, 作为这道题的参数传递
    TreeNode root = utils.getTreeNode();
    System.out.println(hasPathSum(root, 22));
}

我们打印出来看看: 

控制台:

4. 代码 

附上详细注释版:

Java:

public class Leetcode_112 {

    // 全局 路径变量
    public static int path;
    // 目标target, 懒得传参, 也整全局
    public static int target;
    public static boolean hasPathSum(TreeNode root, int targetSum) {
        // 赋初值
        path = 0;
        target = targetSum;
        return dfs(root);
    }

    public static boolean dfs(TreeNode root){
        // 当节点为空 直接返回false
        if(root == null) return false;
        // 先加上当前正在访问节点的值
        path += root.val;
        // 如果正好path已经等于了目标值 同时它还得是[叶子节点] return true
        if(path == target && root.left == null && root.right == null){
            return true;
        }
        // 这个节点遍历完了 但是游戏还没结束
        // 遍历左孩子节点和右孩子节点
        boolean left = dfs(root.left);
        boolean right = dfs(root.right);
        // 两个孩子都处理完了, 自己的任务也完成了, 返回上一层之前先交出它的值
        path -= root.val;
        // 两个孩子 有一个孩子顺利结束战斗 都算成功
        return left || right;
    }
}

简洁版代码:

递归思路熟悉之后, 可以将整体代码简洁为如下:

换个思路, 从结果值开始减:

// 简洁版, 换个思路, 从结果值开始减
public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return false;
        }
        // 如果当前节点为叶子节点
        if (root.left == null && root.right == null) {
            // 判断是否为目标值
            return targetSum == root.val;
        }
        // 当前节点没有顺利完成任务 那么把任务是否胜利的决定权交给左右两个孩子, 减去当前节点的值, 为孩子完成任务所需的目标值
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}

C++:

class Solution {
public:
    // 全局 路径变量
    static int path;
    // 目标target, 懒得传参, 也整全局
    static int target;

    bool hasPathSum(TreeNode* root, int targetSum) {
        // 赋初值
        path = 0;
        target = targetSum;
        return dfs(root);
    }

private:
    bool dfs(TreeNode* root) {
        // 当节点为空 直接返回false
        if (root == nullptr) return false;
        // 先加上当前正在访问节点的值
        path += root->val;
        // 如果正好path已经等于了目标值 同时它还得是[叶子节点] return true
        if (path == target && root->left == nullptr && root->right == nullptr) {
            return true;
        }
        // 这个节点遍历完了 但是游戏还没结束
        // 遍历左孩子节点和右孩子节点
        bool left = dfs(root->left);
        bool right = dfs(root->right);
        // 两个孩子都处理完了, 自己的任务也完成了, 返回上一层之前先交出它的值
        path -= root->val;
        // 两个孩子 有一个孩子顺利结束战斗 都算成功
        return left || right;
    }
};

// 静态成员定义
int Solution::path = 0;
int Solution::target = 0;

JS:

// 全局 路径变量
let path;
// 目标target, 懒得传参, 也整全局
let target;

var hasPathSum = function(root, targetSum) {
    // 赋初值
    path = 0;
    target = targetSum;
    return dfs(root);
};

function dfs(root) {
    // 当节点为空 直接返回false
    if (root === null) return false;
    // 先加上当前正在访问节点的值
    path += root.val;
    // 如果正好path已经等于了目标值 同时它还得是[叶子节点] return true
    if (path === target && root.left === null && root.right === null) {
        return true;
    }
    // 这个节点遍历完了 但是游戏还没结束
    // 遍历左孩子节点和右孩子节点
    const left = dfs(root.left);
    const right = dfs(root.right);
    // 两个孩子都处理完了, 自己的任务也完成了, 返回上一层之前先交出它的值
    path -= root.val;
    // 两个孩子 有一个孩子顺利结束战斗 都算成功
    return left || right;
}

5. 更新预告:

本题做了之后, 可以继续做113. 路径总和 II作为进阶, 让你进一步熟练dfs。

下一步我就会更新113. 路径总和 II, 同样用简单清晰的思路分享给大家。

觉得我的屎山代码能提供帮助的话, 点赞收藏么么哒。

期待下一篇更新的话,可以点点关注mua!, 及时让宝宝们看到。

【简单】力扣算法题解析LeetCode112:路径总和 题目要求判断二叉树中是否存在根节点到叶子节点的路径,使得路径上的节点值之和等于给定的目标值。使用深度优先搜索(DFS)递归遍历所有路径:若当前节点为空返回false;若是叶子节点则检查剩余目标值是否等于节点值;否则递归检查左右子树。时间复杂度O(N),空间复杂度O(H)。代码通过递归实现,优化了短路逻辑以减少冗余计算。示例分析验证了算法的正确性。 阅读详情

相关推荐

CodeBuddy 接入 MCP,一键生成网站!

2024 年 11 月,Anthropic 公司搞了个挺有意思的新玩意 - Model Context Protocol(模型上下文协议)简称为 MCP 协议。简单来说,它就是给 AI 和各类工具数据之间搭了个标准化的”桥梁”,让开发者不用再为对接问题头疼了。mcp.so如下图所示,这是 mcp.so 网站中的 MCP Server。使用百度/高德地图分析旅线计算时间接 Puppeteer 自动操作网页使用 Github/Gitlab 让大模型接管代码仓库。

悟空聊架构的专栏 1941

力扣算法:513.找树左下角的值 112. 路径总和 113. 路径总和 II 106. 从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

力扣算法:513.找树左下角的值 112. 路径总和 113. 路径总和 II 106. 从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

m0_51982291的博客 330

相机光学(三十八)——VCM(Voice Coil Motor)音圈马达

VCM(Voice Coil Motor)音圈马达全称Voice Coil Montor,电子学里面的音圈电机,是马达的一种。因为原理和扬声器类似,所以叫音圈电机,具有高频响、高精度的特点。其主要原理是在一个永久磁场内,通过改变马达内线圈的直流电流大小,来控制弹簧片的拉伸位置,从而带动上下运动。手机摄像头广泛的使用VCM实现自动对焦功能,通过VCM可以调节镜头的位置,呈现清晰的图像。弹片式结构滚珠式结构摩擦式结构Open loop开马达Close loop闭环马达。

图像学习之旅 7209

【LeetCode算法】第112题:路径总和

针对二叉树的路径问题,利用二叉树先序遍历的递归方法可以轻松解决。

致力于Linux的博客 546

BitLocker加密盘解密实战:从隐藏分区到密钥恢复的全过程

本文深入探讨了BitLocker加密盘在密钥丢失或遗忘情况下的解密实战方法。文章系统性地介绍了从理解加密机制、制作取证镜像,到深度扫描隐藏分区、分析内存转储寻找密钥残留,最终利用恢复密钥解锁加密卷的全过程。重点剖析了非标准恢复路径,为数据恢复和数字取证工作提供了专业的技术框架和实战思路。

weixin_29268385的博客 331

Deepracer 智能无人车-绿洲科学云平台介绍

Deepracer 智能无人车 绿洲科学云

woaixiyue19831的博客 1943

LeetCode算法题112:路径总和解析

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 ...

Alex的博客 401

Windows11 下 Detectron2 的安装与配置全攻略

本文提供了在Windows11系统下安装和配置Detectron2的完整教程。详细介绍了从环境准备、创建虚拟环境、安装PyTorch与CUDA,到修改源码、编译安装以及运行验证Demo的全过程,帮助开发者克服Windows平台上的常见问题,成功部署这一强大的计算机视觉库。

weixin_29081703的博客 241

LeetCode算法日记:112.路径总和

123

happykoi的博客 200

看完让你的RSA提升一个台阶 [GKCTF 2021]RRRRsa

我是,今天我给大家分享一个关于RSA的题目,带大家领略的魅力。今天开始前,我们先学习一下。

m0_62102520的博客 848

大模型在心律失常预测及治疗方案制定中的应用研究报告

目录一、引言1.1 研究背景与意义1.2 研究目的与方法1.3 研究创新点二、大模型技术概述2.1 大模型基本原理2.2 常见大模型类型及特点2.3 大模型在医疗领域的应用现状三、心律失常的术前预测与准备3.1 术前心律失常预测的重要性3.2 大模型在术前预测中的应用案例3.3 基于预测结果的术前准备方案四、术中监测与实时调整4.1 术中监测心律失常的方法与技术4.2 大模型辅助术中决策的机制4.3 实时调整手术方案的策略与实践五、术后恢复与并发症风险预测5.1 术后心律失常的监测与评估5.2 大模型预测术

LCG元的博客 1593

来自北大算法课的Leetcode题解:112. 路径总和

(T85% S80%): 树中从根到叶的遍历,同样可以通过递归来做,左子树和右子树是否满足。,终止条件是当前的节点为叶 & 值就是sum。

double_ZZZ的博客 142

【Bug已解决】[Bug]: ValueError: No user query found in messages QWEN 3.5 27B VLLM 0.16.0 NIGHTLY 解决方案

用 vLLM 0.16.0 nightly 给发聊天请求时,服务端在处理消息时抛ValueError,请求失败。

博客 396

LeetCode题解java算法: 112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 示例 2: 输入:root = [1,2,3], targetSum = 5 输出:false 示例 3: 输入:root

wh1236666的博客 215

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

算法:LeetCode112_路径总和_java实现

【代码】算法:LeetCode112_路径总和_java实现。

工匠精神coding,终生学习 136

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

树相关算法之二叉树路径问题:路径总和(LeetCode 112 简单题)、路径总和II(LeetCode 113 中等题)、路径总和III(LeetCode 437,中等题偏难)

本文介绍了LeetCode中路径总和系列问题的解法,包括路径总和(112)、路径总和II(113)和路径总和III(437)。对于简单题112,采用递归判断是否存在满足条件的路径;中等题113通过DFS回溯找到所有符合条件的路径;难题437使用前缀和与DFS回溯结合,统计任意向下路径的数目。三题解法都体现了递归和回溯的思想,但难度递增,解题策略从简单判断逐步发展为需要维护状态信息进行统计。代码实现展示了如何通过递归和回溯高效解决二叉树路径问题。

专注人工智能应用领域 372

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

JavaScript算法21- 路径总和(leetCode:112)

路径总和 一、题目 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。 叶子节点 是指没有子节点的节点。 示例 输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。 二、题解

Y_soybean_milk的博客 1022

每日一道算法题LeetCode112:Path Sum(路径总和 )

路径总和题目分析题解递归 题目 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 分析 题目要求路径必须由根节点到叶节点,就让题目简单了很多,递归一直查到叶节点即可。递归出口有两个,到达叶节点,并且路径和为sum,返回true;到达null节点,返回false 题解 递归 public boolean hasPathSum(TreeNode root, int sum) { if(ro

Alan0_0的博客 351

【Leetcode-02】 112.路径总和 && 437. 路径总和 III

题目 给定一个二叉树,它的每个结点都存放着一个整数值。 找出路径和等于给定数值的路径总数。 路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。 二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。 示例: root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 10 / \ 5 -3 / \ \ 3 2 11 / \ \ 3 -2 1 返回

alovelypeach的博客 358

数据结构与算法之二叉树: LeetCode 112. 路径总和 (Ts, Py, Go版)

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

Wang的专栏 662

java数据结构与算法刷题-----LeetCode112:路径总和

LeetCode112:路径总和

殷志鹏的博客 250

LeetCode刷题复盘笔记—一文搞懂回溯遍历二叉树所有分支路径实现相应功能(112. 路径总和、113. 路径总和 II、129. 求根节点到叶节点数字之和)

LeetCode刷题复盘笔记—一文搞懂回溯遍历二叉树所有分支路径实现相应功能(112. 路径总和、113. 路径总和 II、129. 求根节点到叶节点数字之和)复盘与思考随笔(关注后可以免费获得本人在csdn发布的资源源码)公众号主要记录编程和刷题时的总结复盘笔记和心得!并且分享读书、工作、生活中的一些思考感悟!

Lucky_Alan_Gareth的博客 332

LeetCode 112. 路径总和 II java题解

【代码】LeetCode 122. 买卖股票的最佳时机 II java题解。

乾坤未定,你我皆是黑马 336

[LeetCode] 112_路径总和

[LeetCode]112_路径总和 题目要求 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 ...

寻的学习笔记 238

代码随想录算法训练营打卡第16天:Leetcode513.找树左下角的值,112. 路径总和,113. 路径总和ii,106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树

,言归正传这道题和昨天一样都是使用递归加回溯的组合,然后用集合存取结果,遍历集合之后如果集合元素的值等于目标值,则可以直接返回,如果遍历完没有查到等于目标值的,则直接返回false。之前做的都是使用前序/中序/后序遍历对二叉树进行遍历,现在反过来了,使用遍历过后的数组还原二叉树,首先需要理清楚一下思路首先找到根节点,对于前序或者后序遍历来说,根节点就数组的首位/末尾的元素,接着在中序遍历中锁定根节点的位置,将中序遍历的数组分为两部分,根节点左边的就是左子数组,右边的就是右子数组,以此类推进行递归,

AKA_ZHANG的博客 1615
上一篇: 20分钟速刷十道二叉树层序遍历题
下一篇: 算法:leetcode_113_路径总和Ⅱ
bugMaker_Rehse
博客等级 码龄1年 133粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值