代码学习记录22--回溯算法第三天

随想录日记part22

t i m e : time: time 2024.03.17



主要内容:今天主要是结合类型的题目加深对回溯算法的理解:1.组合总和;2.组合总和
;3.分割回文串。

  • 39. 组合总和
  • 40.组合总和II
  • 131.分割回文串


Topic1组合总和

题目:

给你一个无重复元素的整数数组 c a n d i d a t e s candidates candidates 和一个目标整数 t a r g e t target target ,找出 c a n d i d a t e s candidates candidates 中可以使数字和为目标数 t a r g e t target target 的所有不同组合 ,并以列表形式返回。你可以按任意顺序返回这些组合。
c a n d i d a t e s candidates candidates 中的同一个数字可以无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 t a r g e t target target 的不同组合数少于 150 个。

输入: c a n d i d a t e s = [ 2 , 3 , 6 , 7 ] , t a r g e t = 7 candidates = [2,3,6,7], target = 7 candidates=[2,3,6,7],target=7
输出: [ [ 2 , 2 , 3 ] , [ 7 ] ] [[2,2,3],[7]] [[2,2,3],[7]]

思路: 按照回溯模板我们进行回溯三部曲:
递归三部曲:

1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, p a t h path path用来存放符合条件单一结果, r e s u l t result result用来存放符合条件结果的集合。回溯函数里一定有一个参数记录当前 p a t h path path里面值的和 n o w s u m nowsum nowsum;还需要一个参数为 i n t int int 型变量 s t a r t I n d e x startIndex startIndex
所以整体代码如下:

List<List<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
void backtracking(int target, int start, int nowsum, int[] candidates)

2.回溯函数终止条件
回溯出口,如果 t a r g e t target target 里面的数量等于 n o w s u m nowsum nowsum,说明其到达叶子节点则将其加入到 r e s u l t result result,否则直接返回 r e t u r n return return
代码如下:

if (nowsum > target)return;if (target == nowsum) {result.add(new ArrayList<>(path));return;}

3.回溯搜索的遍历过程
f o r for for 循环每次从 s t a r t I n d e x startIndex startIndex 开始遍历,然后用 p a t h path path 保存取到的节点i搜索的过程如下图:
在这里插入图片描述

实现代码如下:

for (int i = start; i < candidates.length; i++) {path.add(candidates[i]);nowsum += candidates[i];backtracking(target, i, nowsum, candidates);// 不用i+1了,表示可以重复读取当前的数nowsum -= candidates[i];path.removeLast();}

完整的代码如下:

class Solution {List<List<Integer>> result = new ArrayList<>();List<Integer> path = new LinkedList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {result.clear();path.clear();backtracking(target, 0, 0, candidates);return result;}private void backtracking(int target, int start, int nowsum, int[] candidates) {if (nowsum > target)return;if (target == nowsum) {result.add(new ArrayList<>(path));return;}for (int i = start; i < candidates.length; i++) {path.add(candidates[i]);nowsum += candidates[i];backtracking(target, i, nowsum, candidates);// 不用i+1了,表示可以重复读取当前的数nowsum -= candidates[i];path.removeLast();}}
}


Topic2组合总和||

题目:

给定一个候选人编号的集合 c a n d i d a t e s candidates candidates 和一个目标数 t a r g e t target target ,找出 c a n d i d a t e s candidates candidates 中所有可以使数字和为 t a r g e t target target 的组合。 c a n d i d a t e s candidates candidates 中的每个数字在每个组合中只能使用 一次 。注意:解集不能包含重复的组合。

输入: c a n d i d a t e s = [ 10 , 1 , 2 , 7 , 6 , 1 , 5 ] , t a r g e t = 8 candidates = [10,1,2,7,6,1,5], target = 8 candidates=[10,1,2,7,6,1,5],target=8
输出: [ [ 1 , 1 , 6 ] , [ 1 , 2 , 5 ] , [ 1 , 7 ] , [ 2 , 6 ] ] [ [1,1,6], [1,2,5], [1,7], [2,6] ] [[1,1,6],[1,2,5],[1,7],[2,6]]

思路: 按照回溯模板我们进行回溯三部曲:
递归三部曲:

1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, p a t h path path用来存放符合条件单一结果, r e s u l t result result用来存放符合条件结果的集合。回溯函数里一定有一个参数记录当前 p a t h path path里面值的和 n o w s u m nowsum nowsum;还需要一个参数为 i n t int int 型变量 s t a r t I n d e x startIndex startIndex,还有一个用于记录是否被使用过的数组 u s e d used used
所以整体代码如下:

List<List<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
void reback(int[] candidates,int target,int nowsum,int startindex)
boolean[] used;//记录元素是否被用过

2.回溯函数终止条件
回溯出口,如果索引值 s t a r t i n d e x startindex startindex 里面的数量等于 d i g i t s . l e n g t h ( ) digits.length() digits.length(),说明其到达叶子节点,则将 t e m p temp temp其加入到 l i s t list list,否则直接返回 r e t u r n return return
代码如下:

if(target<nowsum)return;if(target==nowsum){result.add(new ArrayList<>(path));}

3.回溯搜索的遍历过程
首先将原始数据进行排序,进行排序后相同的数字就会相邻。如果 c a n d i d a t e s [ i ] = = c a n d i d a t e s [ i − 1 ] 并且 u s e d [ i − 1 ] = = f a l s e candidates[i] == candidates[i - 1] 并且 used[i - 1] == false candidates[i]==candidates[i1]并且used[i1]==false,就说明:前一个树枝,使用了 c a n d i d a t e s [ i − 1 ] candidates[i - 1] candidates[i1],也就是说同一树层使用过 c a n d i d a t e s [ i − 1 ] candidates[i - 1] candidates[i1]。此时 f o r for for 循环里就应该做 c o n t i n u e continue continue 的操作。
在这里插入图片描述

实现代码如下:

for(int i=startindex;i<candidates.length;i++){if(i>startindex && candidates[i]==candidates[i-1])continue;nowsum+=candidates[i];path.add(candidates[i]);used[i]=true;reback(candidates,target,nowsum,i+1);nowsum-=candidates[i];path.removeLast();used[i]=false;}

完整的代码如下:

class Solution {List<List<Integer>> result=new ArrayList<>();//用于记录最后的结果List<Integer> path=new LinkedList<>();//用于记录临时结果boolean[] used;//记录元素是否被用过public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);result.clear();path.clear();used=new boolean[candidates.length];Arrays.fill(used, false);reback(candidates,target,0,0);return result;}private void reback(int[] candidates,int target,int nowsum,int startindex){if(target<nowsum)return;if(target==nowsum){result.add(new ArrayList<>(path));}for(int i=startindex;i<candidates.length;i++){if(i>startindex && candidates[i]==candidates[i-1])continue;nowsum+=candidates[i];path.add(candidates[i]);used[i]=true;reback(candidates,target,nowsum,i+1);nowsum-=candidates[i];path.removeLast();used[i]=false;}}private void reback1(int[] candidates,int target,int nowsum,int startindex){if(target<nowsum)return;if(target==nowsum){result.add(new ArrayList<>(path));}for(int i=startindex;i<candidates.length;i++){if(i>startindex && candidates[i]==candidates[i-1]){continue;}nowsum+=candidates[i];path.add(candidates[i]);reback(candidates,target,nowsum,i+1);nowsum-=candidates[i];path.removeLast();}}
}

时间复杂度: O ( n ∗ 2 n ) O(n * 2^n) O(n2n)
空间复杂度: O ( n ) O(n) O(n)



Topic3分割回文串

题目:

给你一个字符串 s s s,请你将 s s s 分割成一些子串,使每个子串都是回文串。返回 s s s 所有可能的分割方案。

输入: s = " a a b " s = "aab" s="aab"
输出: [ [ " a " , " a " , " b " ] , [ " a a " , " b " ] ] [["a","a","b"],["aa","b"]] [["a","a","b"],["aa","b"]]

思路:

解决该问题需要解决下面几个问题:

  • 切割问题可以抽象为组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串

如何判断回文按照回溯模板我们进行回溯三部曲:
递归三部曲:

1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, p a t h path path用来存放符合条件单一结果, r e s u l t result result用来存放符合条件结果的集合。回溯函数里一定有一个参数记录当前 p a t h path path里面值;还需要一个参数为 i n t int int 型变量 i n d e x index index
所以整体代码如下:

List<List<String>> result = new ArrayList<>();// 存最后的结果
Deque<String> path = new LinkedList<>();// 存中间的结果
void reback(String s, int index)

2.回溯函数终止条件
回溯出口,从树形结构的图中可以看出:切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止条件。
在这里插入图片描述

代码如下:

 if (index >= s.length()) {result.add(new ArrayList(path));return;}

3.回溯搜索的遍历过程
首先判断这个子串是不是回文,如果是回文,就加入在 p a t h path path中, p a t h path path 用来记录切割过的回文子串。

实现代码如下:

for (int i = index; i < s.length(); i++) {if (isHuiwen(s, index, i)) {String str = s.substring(index, i + 1);path.addLast(str);} else {continue;}reback(s, i + 1);path.removeLast();}

完整的代码如下:

class Solution {List<List<String>> result = new ArrayList<>();// 存最后的结果Deque<String> path = new LinkedList<>();// 存中间的结果public List<List<String>> partition(String s) {reback(s, 0);return result;}private void reback(String s, int index) {if (index >= s.length()) {result.add(new ArrayList(path));return;}for (int i = index; i < s.length(); i++) {if (isHuiwen(s, index, i)) {String str = s.substring(index, i + 1);path.addLast(str);} else {continue;}reback(s, i + 1);path.removeLast();}}private boolean isHuiwen(String s, int startIndex, int end) {for (int i = startIndex, j = end; i < j; i++, j--) {if (s.charAt(i) != s.charAt(j)) {return false;}}return true;}
}

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

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

相关文章

【Node.js从基础到高级运用】十四、Node.js 错误处理与日志记录

引言 在这篇博客文章中&#xff0c;我们将深入探讨Node.js中的错误处理和日志记录的最佳实践。我们会了解如何在Node.js应用程序中有效地捕获和处理错误&#xff0c;并利用日志库如morgan来记录应用程序的活动和错误信息。 第1部分&#xff1a;Node.js中的错误处理 同步代码中…

Spring AI Embeddings 和 Vector 入门

在前面 Spring AI Chat 简单示例 中介绍了 Chat 的基本用法&#xff0c;本文在此基础&#xff08;主要是pom.xml&#xff09;上继续探索 Embedding 和 Vector。 官方文档&#xff1a; embeddings: https://docs.spring.io/spring-ai/reference/api/embeddings/openai-embedding…

断点重训教程:如何有效地保护深度学习模型训练进度

在深度学习领域&#xff0c;长时间训练是常见的需求&#xff0c;然而&#xff0c;在训练过程中可能会面临各种意外情况&#xff0c;比如计算机故障、断电等&#xff0c;这些意外情况可能导致训练过程中断&#xff0c;造成已经投入的时间和资源的浪费。为了应对这种情况&#xf…

Avue框架实现图表的基本知识 | 附Demo(全)

目录 前言1. 柱状图2. 折线图3. 饼图4. 刻度盘6. 仪表盘7. 象形图8. 彩蛋8.1 饼图8.2 柱状图8.3 折线图8.4 温度仪表盘8.5 进度条 前言 以下Demo&#xff0c;作为初学者来说&#xff0c;会相应给出一些代码注释&#xff0c;可相应选择你所想要的款式 对于以下Demo&#xff0c…

GStreamer简单看看

主要是现在弄摄像头&#xff0c;要用到这东西。所以学学。 最权威主页&#xff1a;GStreamer: open source multimedia framework 大概看了下&#xff0c;好像命令也不难。 gst-launch-1.0 v4l2src device/dev/video0 ! video/x-raw,formatYUY2,width640,height480,framerat…

说说你对webpack的理解?解决了什么问题?

文章目录 一、背景二、问题三、是什么参考文献 一、背景 Webpack 最初的目标是实现前端项目的模块化&#xff0c;旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候&#xff0c;我们会通过文件划分的形式实现模块化&#xff0c;也就是将每个功能及其相关状态数据各…

Batch Normalization(批量归一化)和 Layer Normalization(层归一化)

Batch Normalization(批量归一化)和 Layer Normalization(层归一化)都是深度学习中用于改善网络训练过程的归一化技术。尽管它们的目标相似,即通过规范化中间层的激活值来加速训练过程并提高性能,但它们在细节上有所不同。 Batch Normalization (批量归一化) Batch Nor…

谷歌地图TMS地图服务地址收集2024,测试可用

对于普通的开发者或者GIS从业者来说&#xff0c;免费的底图影像服务&#xff0c;太重要了。之前写过一篇谷歌地图的TMS地址收集的博文&#xff0c;由于谷歌网站关闭已经不能用。最近又发现了谷歌在国内开放了其他地址&#xff0c;在这里给大家分享一下。 https://gac-geo.googl…

Ant Design Vue和VUE3下的upload组件使用以及文件预览

Ant Design Vue和VUE3下的upload组件使用以及文件预览 文章目录 Ant Design Vue和VUE3下的upload组件使用以及文件预览一、多文件上传1.需求2.样例3.代码 二、单文件上传1. 需求2. 样例3.代码 二、多文件上传产生的时间超时问题三、文件系统名称更改1. 修改文件index.html2. 修…

Leetcode热题100:图论

Leetcode 200. 岛屿数量 深度优先搜索法&#xff1a; 对于这道题来说&#xff0c;是一个非常经典的图的问题&#xff0c;我们可以先从宏观上面来看问题&#xff0c;也就是说在不想具体算法的前提下&#xff0c;简单的说出如何找到所有的岛屿呢&#xff1f; 如图中所示&#x…

oracle 19c单机版本补丁升级

文章目录 一、补丁包概述二、备份opatch三、替换高版本opatch四、打DB补丁1、关闭数据库2、关闭监听3、解压补丁4、冲突检测5、补丁空间检查6、执行补丁升级7、将更新内容加载到数据库8、最后查看数据库版本9、卸载补丁包 一、补丁包概述 补丁升级包 链接&#xff1a;https://…

【系统架构设计师】计算机系统基础知识 03

系统架构设计师 - 系列文章目录 01 系统工程与信息系统基础 02 软件架构设计 03 计算机系统基础知识 文章目录 系统架构设计师 - 系列文章目录 文章目录 前言 一、计算机系统概述 1.计算机组成 ​编辑2.存储系统 二、操作系统 ★★★★ 1.进程管理 2.存储管理 1.页式存储 …

Golang Gorm 自动分批查询

场景&#xff1a; 目标查询全量数据&#xff0c;但需要每次Limit分批查询&#xff0c;保护数据库 文档&#xff1a; https://gorm.io/zh_CN/docs/advanced_query.html // Param: // dest 目标地址 // batchSize 大小 // fc 处理函数func (db *DB) FindInBatc…

安卓 Android Activity 生命周期

文章目录 Intro生命周期方法 & 执行顺序结论code Intro 本文提供一个测试类通过打印的方式展示在多个Activity之间互相跳转的时候&#xff0c;各个Activity的生命周期相关方法的执行顺序。 生命周期方法 & 执行顺序结论 下图出自 郭霖 《第一行代码&#xff08;第二…

电网的正序参数和等值电路(一)

本篇为本科课程《电力系统稳分析》的笔记。 本篇为第二章的第一篇笔记。 电力系统正常运行中&#xff0c;可以认为系统的三相结构和三相负荷完全对称。而对称三相的计算可以用一相来完成&#xff0c;其中所有给出的标称电压都是线电压的有效值&#xff0c;假定系统全部是Y-Y型…

【网站项目】291校园疫情防控系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

The 2023 Guangdong Provincial Collegiate Programming Contest

I. Path Planning 嗯&#xff0c;怎么说呢&#xff0c;一般二维图&#xff0c;数据不是很大的比如n*m*log级别允许的&#xff0c;如果一眼不是bfs&#xff0c;可以考虑结合一下二分 本题可知&#xff0c;只能向下或者向右&#xff0c;那么我们就像如果答案为x&#xff0c;那么…

windows下使用压缩包安装mysql8.0数据库

获取安装包 可以访问mysql 官网下载压缩安装包 &#xff08;官网地址&#xff1a;https://downloads.mysql.com/archives/community/&#xff09; 根据自己的需要&#xff0c;下载对应mysql版本&#xff0c;我选择是是8.0.16版本 安装 解压之后&#xff0c;可以看到压缩包…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《基于老化成本实时次梯度的异构储能系统功率分配策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Vue3 大量赋值导致reactive响应丢失问题

问题阐述 如上图所示&#xff0c;我定义了响应式对象arrreactive({data:[]})&#xff0c;尝试将indexedDB两千条数据一口气赋值给arr.data。但事与愿违&#xff0c;页面上的{{}}在展示先前数组的三秒后变为空。 问题探究 vue3的响应应该与console.log有异曲同工之妙&#xff0…