首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

每日一练:LeeCode-112、路径总和【二叉树+DFS+回溯】

  • 24-03-17 21:10
  • 2103
  • 10432
blog.csdn.net

本文是力扣LeeCode-112、路径总和 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。

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

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

示例 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
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

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

提示:

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

思路

递归法

可以使⽤深度优先遍历的⽅式(本题前中后序都可以,⽆所谓,因为中节点也没有处理逻辑)来遍历⼆叉树

1. 确定递归函数的参数和返回类型

boolean bianLi(TreeNode root, int count)	//需要⼆叉树的根节点,还需要⼀个计数器
  • 1

递归函数什么时候需要返回值?
如果需要搜索整棵⼆叉树且不⽤处理递归返回值,递归函数就不要返回值。
如果需要搜索整棵⼆叉树且需要处理递归返回值,递归函数就需要返回值。
如果要搜索其中⼀条符合条件的路径,那么递归⼀定需要返回值,因为遇到符合条件的路径了就要及时返回。

⽽本题我们要找⼀条符合条件的路径,所以递归函数需要返回值,及时返回,那么返回类型是什么呢?在这里插入图片描述
图中可以看出,遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以⽤bool类型表示

2. 确定终⽌条件
⾸先计数器如何统计这⼀条路径的和呢?
不要去累加然后判断是否等于⽬标和,那么代码⽐较麻烦,可以⽤递减,让计数器count初始为⽬标和,然后每次减去遍历路径节点上的数值。
如果最后count == 0,同时到了叶⼦节点的话,说明找到了⽬标和。
如果遍历到了叶⼦节点,count不为0,就是没找到

 if(root.left==null&&root.right==null&&count==0)return true; // 遇到叶⼦节点,并且计数为0
 if(root.left==null&&root.right==null)return false; //遇到叶⼦节点⽽没有找到合适的边,直接返回
  • 1
  • 2

3. 确定单层递归的逻辑
因为终⽌条件是判断叶⼦节点,所以递归的过程中就不要让空节点进⼊递归了。
递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该⽴刻返回。

        if(root.left!=null){
            count-=root.left.val;	// 递归,处理节点;
            if(bianLi(root.left,count))return true;// 遇到叶⼦节点返回true,则直接返回true
            count+=root.left.val;	// 回溯,撤销处理结果
        }
        if(root.right!=null){
            count-=root.right.val;	// 递归,处理节点;
            if(bianLi(root.right,count))return true;	// 遇到叶⼦节点返回true,则直接返回true
            count+=root.right.val;	// 回溯,撤销处理结果
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
完整代码
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null)return false;
        return bianLi(root,targetSum-root.val);
    }

    boolean bianLi(TreeNode root, int count){
        if(root.left==null&&root.right==null&&count==0)return true;
        if(root.left==null&&root.right==null)return false;
        if(root.left!=null){
            count-=root.left.val;
            if(bianLi(root.left,count))return true;
            count+=root.left.val;
        }
        if(root.right!=null){
            count-=root.right.val;
            if(bianLi(root.right,count))return true;
            count+=root.right.val;
        }
        return false;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

注:最好还是不要精简回溯的过程,把回溯的痕迹写出来,方便写出来

最重要的一句话:做二叉树的题目,首先需要确认的是遍历顺序
大佬们有更好的方法,请不吝赐教,谢谢

注:本文转载自blog.csdn.net的666-LBJ-666的文章"https://blog.csdn.net/kdzandlbj/article/details/136057754"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

113
数据结构与算法
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top