DFS与回溯专题:路径总和问题

embedded/2024/9/22 16:12:42/

    DFS与回溯专题:路径总和问题

一、路径总和

题目链接: 112.路径总和

题目描述

在这里插入图片描述

代码思路

对二叉树进行dfs搜索,递归计算每条路径的节点值之和,当某个节点的左右子节点都为空时,说明已经搜索完成某一条路径,将它与目标值进行比较,若相等,则为true。

代码纯享版

class Solution {public int judge = 0;public boolean hasPathSum(TreeNode root, int targetSum) {int sum = 0;dfs(root, targetSum, sum);return judge == 1;}void dfs(TreeNode root, int targetSum, int sum){if(root == null) return;sum += root.val;if(root.left == null && root.right == null){if(sum == targetSum) judge = 1;return;}dfs(root.left, targetSum, sum);dfs(root.right, targetSum, sum);}
}

代码逐行解析版

class Solution {public int judge = 0; //用于判断是否存在符合题目要求的路径public boolean hasPathSum(TreeNode root, int targetSum) {int sum = 0; //用来统计路径上的节点值dfs(root, targetSum, sum); //对二叉树进行dfs搜索return judge == 1; //如果judge等于1,返回true;否则返回false}void dfs(TreeNode root, int targetSum, int sum){if(root == null) return; //节点为空,直接返回sum += root.val; //将该节点的值加入sum中if(root.left == null && root.right == null){ //该节点的左右子节点都为空时,说明搜索到了一条完整的路径if(sum == targetSum) judge = 1; //如果sum与目标和相等,judge变成1return;}//到这一步说明路径还没搜索完,接下来搜索该节点的左右子节点dfs(root.left, targetSum, sum);dfs(root.right, targetSum, sum);}
}

代码有关问题的解释

统计时sum的数值为什么不需要进行清零之类的操作?
递归是「隐式」回溯:使用一个整型变量(比如sum)来累加路径上的节点值,则在递归的过程中就不需要显式地进行撤回操作了。这是因为每次递归调用时,sum的值是通过参数传递的,每一层的递归调用都有自己的sum副本,这些副本互不影响。

二、路径总和 II

题目链接: 113.路径总和 II

题目描述

在这里插入图片描述

代码思路

算法流程:
函数 pathSum(root, targetSum) :

初始化: 结果列表 list_all ,路径列表 list 。
返回值: 返回 list_all 即可。
函数 dfs(root, targeSum,sum):

递推参数: 当前节点 root ,当前目标值 sum == targetSum 。
终止条件: 若节点 root 为空,则直接返回。
递推工作:
路径更新: 将当前节点值 root.val 加入路径 list 。
目标值更新: sum += root.val
路径记录: 当 root 为叶节点 且 路径和sum等于目标值 ,则将此路径 list 加入 list_all 。
先序遍历: 递归左 / 右子节点。
路径恢复: 向上回溯前,需要将当前节点从路径 list 中删除,即执行list.remove(list.size() - 1) 。

#代码纯享版

class Solution {public List<List<Integer>> list_all = new ArrayList();public List<Integer> list = new  ArrayList();public List<List<Integer>> pathSum(TreeNode root, int targetSum) {int sum = 0;dfs(root, targetSum, sum);return list_all;}void dfs(TreeNode root, int targetSum, int sum){if(root == null){return;}sum += root.val;list.add(root.val);if(root.left == null && root.right == null && sum == targetSum){list_all.add(new ArrayList(list)); }dfs(root.left, targetSum, sum);dfs(root.right, targetSum, sum);list.remove(list.size() - 1);}
}

代码逐行解析版

class Solution {public List<List<Integer>> list_all = new ArrayList(); //记录所有符合条件的路径public List<Integer> list = new  ArrayList(); //记录搜索过程中的路径public List<List<Integer>> pathSum(TreeNode root, int targetSum) {int sum = 0; //用来统计路径上的节点值dfs(root, targetSum, sum); //对二叉树进行dfs搜索return list_all; //返回路径的列表}void dfs(TreeNode root, int targetSum, int sum){if(root == null){ //节点为空,直接返回return;}sum += root.val; //将该节点的值加入sum中list.add(root.val); //将节点添加到路径中if(root.left == null && root.right == null && sum == targetSum){ //如果路径走完且与目标值相同list_all.add(new ArrayList(list)); //将路径添加到list_all(浅拷贝)}//到这一步说明路径还没搜索完,接下来搜索该节点的左右子节点dfs(root.left, targetSum, sum);dfs(root.right, targetSum, sum);//删掉路径列表中最后一个节点list.remove(list.size() - 1);}
}

代码相关问题的解释

为什么要写list_all.add(new ArrayList(list)),而不是list_all.add(list)?
注意:解释里面的sum.add(path)就是list_all.add(list)
在这里插入图片描述


http://www.ppmy.cn/embedded/11716.html

相关文章

GPT国内能用吗

2022年11月&#xff0c;Open AI发布ChatGPT&#xff0c;ChatGPT展现了大型语模型在自然语言处理方面的惊人进步&#xff0c;其生成文本的流畅度和连贯性令人印象深刻&#xff0c;为AI应用打开了新的可能性。 ChatGPT的出现推动了AI技术在各个领域的应用&#xff0c;例如&#x…

DPDK helloworld 解析

1. 学习目的 计划通过学习 DPDK 官方提供的 demo&#xff0c; 对 DPDK API 的使用有一些了解&#xff0c;helloworld 程序是其中最简单的程序&#xff0c;还是实际上手学习能更快一些。 2. 编译 helloworld 源码 环境变量设置&#xff1a; export RTE_SDK/home//dpdk/dpdk-stab…

「Qt Widget中文示例指南」如何实现行编辑功能

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 Line Edits&#xf…

外包干了6个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

vue 实现级联选择器功能

vue开发中&#xff0c;通过使用 Element UI 的 el-cascader 组件来实现级联选择器功能,下面是一个示例代码&#xff0c;演示如何使用 el-cascader 组件初始化级联选择器&#xff0c;并设置默认值为单位 测试1 和部门 测试11 <template><div><el-cascaderv-mode…

history命令

history 命令&#xff1a; history 命令用于显示当前用户在命令行中输入的历史命令列表。它会列出之前执行过的所有命令&#xff0c;每条命令都会有一个编号。这个命令不进行过滤或搜索&#xff0c;只是简单地列出了所有的命令历史记录。 history | grep “git”&#xff1a;…

Linux系统安全:从面临的攻击和风险到安全加固、安全维护策略(文末有福利)

1. Linux面临的攻击与风险 1.1. Linux系统架构 Linux系统架构解读&#xff1a; 用户之间隔离内核态与用户态之间隔离用户进程一般以低权限用户运行系统服务一般以特权服务运行用户态通过系统调用进入内核态内核对系统资源进行管理和分配 1.2. Linux系统常见安全威胁 1.2.1.…

Linux进程详解二:创建、状态、进程排队

文章目录 进程创建进程状态进程排队 进程创建 pid_t fork(void) 创建一个子进程成功将子进程的pid返回给父进程&#xff0c;0返回给新创建的子进程 fork之后有两个执行分支&#xff08;父和子&#xff09;&#xff0c;fork之后代码共享 bash -> 父 -> 子 创建一个进…