力扣113题引发的关于DFS和回溯的一点思考

news2024/12/30 1:14:48
  1. 最近刚学回溯和DFS,刷力扣遇到一道题(113题),如下:
    在这里插入图片描述
  2. 我们不细究回溯和DFS的区别联系。关于这道题的2种写法,我把第一种称为回溯。
class Solution {
    List<List<Integer>> res = new LinkedList<>();
    LinkedList<Integer> trace = new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        //标准回溯写法
        if (root == null) return res;
        trace.add(root.val);
        targetSum -= root.val;
        backTrack(root, targetSum);
        return res;
    }
    void backTrack (TreeNode root, int targetSum) {
        //标准的回溯写法:1.结束条件2.可选择项:递归调用4.对每一个选择项回溯
        //这种回溯的写法需要先对根节点进行选择。

        //结束条件
        if (0 == targetSum && root.left == null && root.right == null) {
              res.add(new LinkedList<>(trace));
        };
        //可选择项(把节点上的值,看成所在分支)
        if (root.left != null) {
            trace.add(root.left.val);
            targetSum -= root.left.val;
            backTrack(root.left, targetSum); //递归调用
            //回溯
            trace.removeLast();
            targetSum += root.left.val;
        }
        //可选择项(把节点上的值,看成所在分支)
        if (root.right != null) {
            trace.add(root.right.val);
            targetSum -= root.right.val;
            backTrack(root.right, targetSum); //递归调用
            //回溯
            trace.removeLast();
            targetSum += root.right.val;
        }
    }
}

我把第二种方法称为DFS,代码如下:

class Solution {
    List<List<Integer>> res = new LinkedList<>();
    LinkedList<Integer> trace = new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        if (root == null) return res;
        trace.add(root.val);
        targetSum -= root.val;
        if (root.left == null && root.right == null && targetSum == 0) {
            res.add(new LinkedList<>(trace));
        }
        pathSum(root.left, targetSum);
        pathSum(root.right, targetSum);
        trace.removeLast();
        targetSum += root.val;
        return res;
    }
 }
  1. 我们知道回溯的标准框架:
backtrack (当前状态) {
	1.判断结束条件
	2.根据当前状态获取下一个状态的选项列表,然后递归
	for (可选项:可选项列表){
		处理可选项;
		backTrack(可选项);
		撤销可选项;
	}
}

回溯框架的应用场景一般是对分支做选择,而我们这道题的选项都是节点,对于上述的回溯代码,需要把这些节点变成分支,再去套用回溯框架可能更好理解一些。我把节点上的值变到分支上,如图:
在这里插入图片描述
接下来,就是套用回溯的框架了,那么我们如何开始调用backtrack()方法呢,具体来说,我们的backtrack方法中传入的root应该是啥呢?值得注意的是,我们的backtrack方法的第一个参数的作用纯粹是为了引出后续的可选分支,我们加入路径的也是后续的可选分支,我们的backtrack方法不对第一个参数(一个分支)做其他事情,通过上图,我们可以看到我们需要通过第一个5这个分支引出4和8这两个分支,而在backtrack这个方法中,5这个分支我们就不会考虑到了,所以我们需要手动去访问5这个分支,并加入路径,也就对应代码:

if (root == null) return res;
trace.add(root.val);
targetSum -= root.val;

有了这一层铺垫之后,后序就可以不断地: 引出可选项–>递归–>回溯了。
4. 我们把第二种方法就叫DFS吧(虽然回溯思想也需要用到DFS算法)。
第二种方法处理的就是节点,我们也可以仿照回溯的代码框架来,但是需要注意不同之处。

  • dfs()方法中虽然第一个参数(一个节点)也用于引出后序节点,但是dfs()也会访问这个节点,也就是加入路径,而backtrack第一个参数在调用之前就已经访问过了。
  • 可以看到,dfs()是先处理访问节点,再去判断是否结束,而backtrack直接就判断了。
  • 因为回溯和dfs对分支和节点的处理时机不同,导致撤销选择时机不同。如下图代码框架:
    在这里插入图片描述

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

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

相关文章

29.Nacos的简介与安装(springcloud)

1.Nacos 简介官网&#xff1a; https://nacos.io/zh-cn/Nacos 致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是…

【Android Studio Gradle】发布aar到私有Artifactory仓库

1. 前言 在【Android Studio Gradle】使用Artifactory构建本地仓库中介绍了如何利用工具配置一个maven私有库&#xff0c;那么在开发library的时候为了方便难免会用到需要将该库发布到这个仓库的功能。经过测试和配置&#xff0c;确实在Artifactory仓库中也可以通过gradlew命令…

【MySQL基础】为什么大部分人选择使用MySQL数据库?

目录 一、为什么大部分人选择使用MySQL数据库&#xff1f; 二、MySQL简介 1.MySQL介绍 2.MySQL的特点 3. MySQL的版本 从用户的角度&#xff0c;针对不同的用户 从单纯的版本数字区分 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f49…

我把皮小浪の的 蓝色妖姬系列做进了java窗口

— &#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏 unity实战入门 ⭐效果图如下 ⭐⭐涉及的相关类的包含关系图 ⭐# 视频入口&#xff1a;请点击 文章目录一…

比 O(nlog(n)) 做得更好——2.改变问题以及排序和填充数组

改变问题&#xff0c;以及对键进行排序和填充数组。 目录 【第1篇】比 O(nlog(n)) 做得更好——1.创造合适的条件 长按关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 扫码关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 …

【Redis-04】Redis两种持久化方式

Redis是基于内存的数据结构服务器&#xff0c;保存了大量的键值对数据&#xff0c;所以持久化到磁盘是非常必要的&#xff0c;Redis提供了两种持久化的方式&#xff0c;分别是RDB和AOF。下面我们看下这两种持久化方式的具体实现原理。 1.RDB持久化 首先&#xff0c;RDB持久化方…

【Spring(二)】java对象属性的配置(Bean的配置)

有关Spring的所有文章都收录于我的专栏&#xff1a;&#x1f449;Spring&#x1f448; 目录 一、前言 二、通过Setter方法配置Bean 三、通过构造器配置Bean   1. 通过属性名配置   2. 通过索引配置   3. 通过属性类型配置 四、通过p命名空间配置bean 五、引用/注入其他bean…

openEuler快速入门-openEuler系统安装openGauss数据库安装

文章目录前言一、安装openEuler系统安装二、运行虚拟机&#xff0c;配置三、安装openGauss数据库总结前言 openEuler&#xff1a;openEuler 是一款开源操作系统。当前 openEuler 内核源于 Linux&#xff0c;支持鲲鹏及其它多种处理器&#xff0c;能够充分释放计算芯片的潜能&a…

[附源码]java毕业设计网络身份认证技术及方法

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

_001_Zotero入门

Zetoro大纲一、安装Zotero二、收集题录2.1 浏览器插件2.2 通过标识符添加2.3 拖拽文献2.4 从剪切板导入2.5 批量导入2.6 手动添加&#xff08;不建议使用&#xff09;2.7 方法总结三、管理题录3.1 移动分类3.2 查重3.3 关联3.4 标签3.5 笔记3.6 RSS订阅3.7 快捷键3.8 总结四、在…

Verilog 时序逻辑 UDP

时序逻辑 UDP 与组合逻辑 UDP 在定义形式和行为功能上均有不同&#xff0c;主要区别如下&#xff1a; 1、时序逻辑 UDP 的输出端必须声明为 reg 型。2、时序逻辑 UDP 可以用 initial 语句初始化。3、状态表格式也稍有不同&#xff1a; ... : <current_state> : &l…

RabbitMQ初步到精通-第七章-RabbitMQ之延迟队列

目录 第七章-RabbitMQ之延迟队列 1. 延迟队列概念 2. 应用场景 3. 架构模式 3.1 队列TTL实现 3.2 消息TTL实现 3.3 插件实现 4. 代码验证 5. 总结 第七章-RabbitMQ之延迟队列 1. 延迟队列概念 延迟-意即 非实时&#xff0c;之前我们讨论大部分的案例都是生产者将消息发…

【毕业设计】61-基于单片机的超声波测距仪设计(原理图、仿真工程、低重复率参考设计文档、PPT、开题报告、任务书)

【毕业设计】61-基于单片机的超声波测距仪设计&#xff08;原理图、仿真工程、低重复率参考设计文档、PPT、开题报告、任务书&#xff09;[toc] 资料下载链接 资料下载链接 资料链接&#xff1a;https://www.cirmall.com/circuit/33762/ 包含此题目毕业设计全套资料&#xff…

UDS应用场景

诊断协议那些事儿 本文为诊断协议那些事儿专栏文章&#xff0c;旨在介绍诊断的应用场景&#xff0c;其本质就是一个用于汽车行业通信的需求规范&#xff0c;用于诊断功能数据的解析&#xff01;让读者对诊断有一个深入的认识。 关联文章&#xff1a;UDS协议发展历史 文章目录…

idea如何设置代理实现管理突破呢

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

抗锯齿渲染

&#xff08;逻辑绘图&#xff09;图像在坐标图中的显示&#xff1a; 笔的默认宽度为1&#xff0c;当笔的宽度大于1时&#xff0c;相当于在则条线的两边均匀加厚&#xff0c;确定坐标的还是这条宽度为1的线段&#xff0c;相当于宽度的中心位置。 物理绘图 &#xff08;默认情况…

集成学习、装袋法、提升法、GBDT、随机森林(机器学习)

集成学习 集成学习(Ensemble learning)是机器学习中近年来的一大热门领域。其中的 集成方法是用多种学习方法的组合来获取比原方法更优的结果 使用于组合的算法是弱学习算法 即分类正确率仅比随机猜测略高的学习算法 但是组合之后的效果仍可能高于强学习算法 即集成之后的…

总抱怨Mac运行速度又卡又慢?这些方法你用得上

通常大家处理Mac运行速度慢的方法不是重启就是清空废纸篓&#xff0c;但是这两种方法对于Mac提速性能的效果是微之甚微的&#xff0c;想要彻底解决Mac运行速度慢&#xff0c;你应该试试一下三种方法~ 1、清理磁盘空间 硬盘空间过少是Mac运行变慢很大的一个因素&#xff0c;各种…

第03章_基本的SELECT语句

第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年&#xff0c;世界上第一台电脑诞生&#xff0c;如今&#xff0c;借由这台电脑发展起来的互联网已经自成江湖。在这几十年里&#xff0c;无数的技术、产业在这片江湖里沉浮&#xff0c;有的方兴未艾&#xff0c;有…

【用户画像】Redis的常用五大数据类型和配置文件介绍

文章目录一 常用五大数据类型简介1 Redis键(key)2 Redis字符串(String)3 Redis列表(List)4 Redis集合(Set)5 Redis哈希(Hash)6 Redis有序集合Zset(sorted set)二 Redis配置文件介绍1 UNITS2 INCLUDES3 NETWORK4 MEMORY MANAGEMENT一 常用五大数据类型简介 常用命令 1 Redis键…