秋招力扣Hot100刷题总结——回溯

回溯问题通常应用于解决排列组合等问题,需要注意的是回溯函数中的参数、结束条件、遍历开始顺序等。
回溯三部曲:
(1)确定递归函数的参数。
(2)确定递归函数的终止条件。
(3)确定单层搜索的逻辑。

1.全排列 题目链接

  • 题目要求:给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
    在这里插入图片描述
  • 代码及思路
    • 使用回溯求排列
    • 回溯结束条件:当前集合的元素个数等于nums数组中元素个数
    • 在回溯的每一层中,选择当前未被使用的数字加入当前排列,使用used数组记录已经使用过的元素
    • 代码
class Solution {List<List<Integer>> res=new ArrayList<>();public List<List<Integer>> permute(int[] nums) {boolean[] used=new boolean[nums.length];backTracing(nums,used,new ArrayList<>());return res;}private void backTracing(int[] nums,boolean[] used,List<Integer> path){if(path.size()==nums.length){res.add(new ArrayList<>(path));return;}for(int i=0;i<nums.length;i++){if(!used[i]){used[i]=true;path.add(nums[i]);backTracing(nums,used,path);used[i]=false;path.remove(path.size()-1);}}}
}

2. 电话号码的字母组合 题目链接

  • 题目要求:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
    给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
    在这里插入图片描述
  • 代码及思路
    • 回溯的参数为输入字符串digits,电话号码对应的字符串数组,以及处理到digits中数字的顺序
    • 结束条件为:但处理到的数字的顺序大于等于digits的长度时,就可以添加到结果中并返回了
    • 回溯中循环直接从0开始,因为这是在多个不同的字符串中进行组合,不需要考虑重复问题
    • 代码
class Solution {List<String> res=new ArrayList<>();public List<String> letterCombinations(String digits) {if(digits.length()==0)return res;String[] numbers={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};backTracing(digits,0,numbers);return res;}StringBuilder path=new StringBuilder();private void backTracing(String digits,int start,String[] numbers){if(start>=digits.length()){res.add(path.toString());return;}String str=numbers[digits.charAt(start)-'0'];for(int i=0;i<str.length();i++){path.append(str.charAt(i));backTracing(digits,start+1,numbers);path.deleteCharAt(path.length()-1);}}
}

3. 路径总和 III(回溯+前缀和)题目链接

  • 题目要求:给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
    路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
    在这里插入图片描述
  • 代码及思路
    • 因为每个节点都可能有左右节点,因此需要回溯考虑多种情况
    • 使用前缀和来判断路径和
    • 代码
class Solution {public int pathSum(TreeNode root, int targetSum) {if(root==null)return 0;Map<Long,Integer> presum=new HashMap<>();//注意,主要是为了考虑从根节点开始到某个节点之间的路径刚好等于targetpresum.put(0L,1);return dfs(root,presum,0L,targetSum);}private int dfs(TreeNode root,Map<Long,Integer> presum,Long cur,int targetSum){if(root==null)return 0;int res=0;cur+=root.val;res+=presum.getOrDefault(cur-targetSum,0);presum.put(cur,presum.getOrDefault(cur,0)+1);res+=dfs(root.left,presum,cur,targetSum);res+=dfs(root.right,presum,cur,targetSum);//回溯presum.put(cur,presum.get(cur)-1);return res;}
}

4. 括号生成 题目链接

  • 题目描述:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
    在这里插入图片描述
  • 代码及思路
    • 使用回溯解决问题,递归时当当前字符串的长度等于n的两倍时添加到结果集中
    • 当左括号数量小于n时,继续递归添加左括号
    • 当右括号数量小于左括号数量时递归添加右括号
    • 代码
class Solution {List<String> res=new ArrayList<>();public List<String> generateParenthesis(int n) {backTracing("",0,0,n);return res;}private void backTracing(String cur,int left,int right,int n){if(cur.length()==2*n){res.add(cur);}if(left<n){backTracing(cur+"(",left+1,right,n);}if(right<left){backTracing(cur+")",left,right+1,n);}}}

5. 子集 题目链接

  • 题目要求:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
    解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
    在这里插入图片描述
  • 代码及思路
    • 使用回溯解决问题,每次递归时起始位置加1,避免元素重复
    • 每一次递归过程都将当前的路径集合加入结果集
    • 当path的长度等于数组的个数时结束递归
    • 代码
class Solution {List<List<Integer>> res=new ArrayList<>(); public List<List<Integer>> subsets(int[] nums) {backTracing(nums,0,new ArrayList<>());return res;}private void backTracing(int[] nums,int start,List<Integer> path){res.add(new ArrayList<>(path));if(start>=nums.length){return;}for(int i=start;i<nums.length;i++){path.add(nums[i]);backTracing(nums,i+1,path);path.remove(path.size()-1);}}}

6. 组合总数 题目链接

  • 题目要求:给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
    candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
    对于给定的输入,保证和为 target 的不同组合数少于 150 个。
    在这里插入图片描述
  • 代码及思路
    • 使用回溯解决,每次回溯的起始位置都是当前遍历的元素
    • 当target刚好等于0的时候将当前结果加入结果集并结束递归
    • 当target小于0时,结束递归
    • 代码
class Solution {List<List<Integer>> res=new ArrayList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {backTracing(candidates,0,target,new ArrayList<>());return res;}private void backTracing(int[] candidates,int start,int target,List<Integer> path){if(target==0){res.add(new ArrayList<>(path));return;}if(target<0){return;}for(int i=start;i<candidates.length;i++){path.add(candidates[i]);backTracing(candidates,i,target-candidates[i],path);path.remove(path.size()-1);}}
}

7.目标和 题目链接

  • 题目要求:给你一个非负整数数组 nums 和一个整数 target 。
    向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 :
    例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。
    返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
    在这里插入图片描述
  • 代码及思路
    • 使用回溯来解决问题
    • 首先对每一个数字可能添加的不同符号进行考虑,并对每一种情况进行递归
    • 每一个数字的返回结果是两种不同符号的和
    • 递归结束条件:遍历到数组结束
    • 代码
class Solution {public int findTargetSumWays(int[] nums, int target) {return backTracing(nums,target,0,0);}private int backTracing(int[] nums, int target, int index, int currentSum) {if (index == nums.length) {// 当遍历完所有的数字后,判断当前的和是否等于目标值return currentSum == target ? 1 : 0;}// 选择将当前数字添加正号int add = dfs(nums, target, index + 1, currentSum + nums[index]);// 选择将当前数字添加负号int subtract = dfs(nums, target, index + 1, currentSum - nums[index]);// 返回两种选择的总和return add + subtract;}
}

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

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

相关文章

SQL进阶技巧:最近有效的缺失值填充问题【last_value实现版】

目录 0 场景描述 1 数据准备 2 问题分析 3 小结 0 场景描述 场景:现在有一张商品入库表,包括商品id、商品成本和入库日期3个字段,由于某些原因,导致部分商品的成本缺失(为0或者没有值都是缺失),这样不利于我们计算成本。所以现在要把缺失的商品进价补充完整,补充的…

Hive3:常用查询语句整理

一、数据准备 建库 CREATE DATABASE itheima; USE itheima;订单表元数据 1 1000000 100058 6 -1 509.52 0.00 28155.40 499.33 0 0 lisi shanghai 157 2019-06-22 17:28:15 2019-06-22 17:28:15 1 2 5000000 100061 72 -1 503.86 0.00 38548.00 503.86 1 0 zhangsan shangha…

如何让虚拟机识别到宿主机的USB设备

我的实验环境&#xff1a; Windows宿主机VirtualBox虚拟化软件一个Linux虚机一个8G的USB磁盘 首先要让虚拟机能看到宿主机的USB设备&#xff0c;这是在VirtualBox中设置的。 选中虚机&#xff0c;右键选择“设置”菜单&#xff0c;再单击“USB设备”&#xff1a; 选中“启用…

【分布式系统】关于主流的几款分布式链路追踪工具

Jaeger 标准化与兼容性&#xff1a; Jaeger 支持 OpenTracing 和 OpenTelemetry 标准&#xff0c;这意味着它可以与各种微服务架构和应用框架无缝集成&#xff0c;提供了广泛的兼容性和灵活性。 数据存储选项&#xff1a; Jaeger 支持多种数据存储后端&#xff0c;如 Cassandra…

白卡无法注册TDSCDMA问题分析

1、问题描述 MTK平台 实验室白卡测试TDSCDMA&#xff0c;默认无法注册。使用移动卡测试&#xff0c;无此问题。 2、问题分析 查看Radio log&#xff0c;Radio中反复下发EFUN去开关飞行模式。 39191: 08-14 22:45:57.159210 1469 1512 D RmcWp : [0] ECSRA info E…

UE4编安卓时Core模块为何只include Android文件夹?

Core模块 Core模块是整个引擎中最核心的模块。几乎UE4中的每个其他模块都导入Core。Engine\Source\Runtime\Core\Private下有很多文件夹&#xff0c;下面罗列一部分&#xff1a; G:\St\EngineSource\Engine\Source\Runtime\Core\Private 的目录 2024/07/18 12:02 <DIR…

在Linux中更换软件源

在Linux中更换软件源&#xff0c;通常是编辑 /etc/apt/sources.list 文件或者在 /etc/apt/sources.list.d/ 目录下的相关.list文件。以下是更换为阿里云源的例子&#xff1a; 1.备份原有的 sources.list 文件&#xff1a; sudo cp /etc/apt/sources.list /etc/apt/sources.li…

学习笔记七:基于Jenkins+k8s+Git+DockerHub等技术链构建企业级DevOps容器云平台

基于Jenkinsk8sGitDockerHub等技术链构建企业级DevOps容器云平台 安装Jenkins在kubernetes中部署jenkins创建名称空间创建pv,上传pv.yaml创建pvc创建一个sa账号通过deployment部署jenkins更新资源清单文件把jenkins前端加上service&#xff0c;提供外部网络访问 配置Jenkins获取…

数学建模学习(116):全面解析梯度下降算法及其在机器学习中的应用与优化

文章目录 1.梯度下降简介1.1 梯度下降的数学原理1.2 学习率的选择2 梯度下降变体3.梯度下降优化器3.1 动量法(Momentum)3.2 AdaGrad3.3 RMSprop3.4 Adam3.5 Python 使用不同优化器训练线性回归模型4.案例:使用梯度下降优化加利福尼亚房价预测模型4.1. 数据准备4.2. 模型训练…

功能测试和性能测试区别简析,软件测试公司如何开展有效测试?

软件功能测试旨在验证软件是否按照需求和设计规范正常运行&#xff0c;软件性能测试则是用来评估软件在特定负载条件下的行为和响应时间&#xff0c;确保软件在高并发和高需求的环境中能够稳定运行。 虽然两者都属于软件测试的重要组成部分&#xff0c;但它们的目的和重点却有…

sp2杂化 与 sp3杂化

sp杂化 概念&#xff1a;当碳原子采用sp杂化时&#xff0c;它会把一个2s轨道和两个2p轨道混合&#xff0c;形成三个能量相同、方向呈120角的杂化轨道。这些轨道平面呈三角形排列。键的形成&#xff1a;在这种杂化状态下&#xff0c;碳原子会形成三个σ键&#xff08;单键&…

依赖倒置原则(Dependency Inversion Principle, DIP)

依赖倒置原则&#xff08;Dependency Inversion Principle, DIP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它旨在降低代码之间的耦合度&#xff0c;提高系统的可维护性、可扩展性和灵活性。这一原则的核心思想是要求高层模块不应该依赖于低层模块&#xff0c;而应…

《区块链:共享经济发展的创新驱动力》

在当今数字化时代&#xff0c;共享经济以其高效利用资源、降低成本和创造新的价值模式等优势&#xff0c;迅速崛起并改变着人们的生活和消费方式。然而&#xff0c;共享经济在发展过程中也面临着一系列挑战&#xff0c;如信任缺失、数据安全、交易成本高等。区块链技术的出现&a…

【Java-==与equals】

与equals区别&#xff1a; 1.是关系运算符&#xff0c;equals()是0bject类中定义的方法 2.基本数据类型: 使用比较值&#xff0c;无法使用equals() 3.引用数据类型: 使用比较内存地址; 如果没有重写equals(),仍然调用的是0bject父类的equals(()方法&#xff0c;则比较的是内…

开发团队学会应对突发的技术故障和危机

文章目录 一、前言二、应对方法2.1 建立应急响应计划2.2 实时监控与预警2.3 快速定位问题2.4 沟通和协调2.5 调整资源2.6 快速评估影响2.7 利用风险管理工具2.8 备份与恢复策略2.9 客户沟通2.10 事后总结与改进2.11 总结和反思 三、总结 一、前言 8月19日下午&#xff0c;网易…

Leetcode-day30-动态规划-不同路径

62. 不同路径 这个题动态规划的特征比较明显&#xff0c;我们就看终点&#xff0c;到终点的不同路径就等于要么从他上面一格往下走一格&#xff0c;要么从他左边一个往右走一格&#xff0c;所以可以得出递推公式。 动态规划五部曲&#xff1a; 1. 确定dp数组的含义&#xff0…

【经典算法】BFS_最短路问题

目录 1. 最短路问题介绍2. 算法原理和代码实现(含题目链接)1926.迷宫中离入口最近的出口433.最小基因变化127.单词接龙675.为高尔夫比赛砍树 3. 算法总结 1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问…

手机谷歌浏览器怎么用

谷歌浏览器不仅在PC端受欢迎&#xff0c;在移动端也是广泛应用的。为了帮助大家更好的理解和使用手机谷歌浏览器&#xff0c;本文将详细介绍如何使用手机谷歌浏览器&#xff0c;对这款浏览器感到陌生的话就快快学起来吧。&#xff08;本文由https://chrome.cmrrs.com/站点的作者…

element-plus默认菜单打开

在 Vue 3 中使用 Element Plus 的 <el-menu> 组件时&#xff0c;默认情况下菜单项是关闭状态的。如果你想让某个菜单项默认处于展开状态&#xff0c;你可以通过设置菜单项的 default-active 属性来实现。 默认写法 步骤 1: 设置 default-active 你需要在 <el-menu&…

《分析模式:可重用对象模型》学习笔记之四:企业财务分析中的观察和测量06

下面是一些用Java 给出的代码示例&#xff08;Sample code&#xff09;&#xff0c;是作者最喜欢的Date Range。 class DateRange... public DateRange (Date start, Date end) { this (new MfDate(start), new MfDate(end)); } public DateRange (MfDate start, MfDate end) {…