代码学习记录21--回溯算法第二天

随想录日记part21

t i m e : time: time 2024.03.16



主要内容:今天主要是结合类型的题目加深对回溯算法的理解:1:组合总和;2:电话号码的字母组合

  • 216.组合总和III
  • 17.电话号码的字母组合


Topic1组合总和

题目:

找出所有相加之和为 n n n k k k 个数的组合,且满足下列条件:

  • 只使用数字 1 1 1 9 9 9
  • 每个数字最多使用一次

返回所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

输入: k = 3 , n = 9 k = 3, n = 9 k=3,n=9
输出: [ [ 1 , 2 , 6 ] , [ 1 , 3 , 5 ] , [ 2 , 3 , 4 ] ] [[1,2,6], [1,3,5], [2,3,4]] [[1,2,6],[1,3,5],[2,3,4]]
解释:
1 + 2 + 6 = 9 1 + 2 + 6 = 9 1+2+6=9
1 + 3 + 5 = 9 1 + 3 + 5 = 9 1+3+5=9
2 + 3 + 4 = 9 2 + 3 + 4 = 9 2+3+4=9
没有其他符合的组合了。

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

1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, p a t h path path用来存放符合条件单一结果, r e s u l t result result用来存放符合条件结果的集合。回溯函数里一定有两个参数,既然是集合 [ 1 , 9 ] [1,9] [1,9] 里面取 k k k 个数和为 n n n,所以需要 n n n k k k 是两个 i n t int int 的参数。还需要一个参数为 i n t int int 型变量 s t a r t I n d e x startIndex startIndex,这个参数用来记录本层递归的中,集合从哪里开始遍历(集合就是 [ 1 , . . . , n ] [1,...,n] [1,...,n] )。
所以整体代码如下:

List<List<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
private void backtracking(int n,int k, int statindex){}

2.回溯函数终止条件
回溯出口,如果 p a t h path path 里面的数量等于 K K K,说明其到达叶子节点,若 p a t h path path 中所有元素之和为 n n n,则将其加入到 r e s u l t result result,否则直接返回 r e t u r n return return
代码如下:

if (k == path.size()) {// 回溯出口,如果Path里面的数量等于K,说明其到达叶子节点int sum = 0;for (int i = 0; i < k; i++) {sum += path.get(i);}if (sum == targetSum)result.add(new ArrayList<>(path));return;// 如果path.size() == k 但sum != targetSum 直接返回}

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 = startindex; i <= 9; i++) {path.add(i);backtracking(targetSum, k, i + 1);path.removeLast();}

完整的代码如下:

class Solution {List<List<Integer>> result = new ArrayList<>();// 存放结果集合LinkedList<Integer> path = new LinkedList<>();// 存放一个满足条件的路径public List<List<Integer>> combinationSum3(int k, int n) {result.clear();path.clear();backtracking(n, k, 1);return result;}// targetSum:目标和,也就是题目中的n。// k:题目中要求k个数的集合。// startIndex:下一层for循环搜索的起始位置。private void backtracking(int targetSum, int k, int startindex) {if (k == path.size()) {// 回溯出口,如果Path里面的数量等于K,说明其到达叶子节点int sum = 0;for (int i = 0; i < k; i++) {sum += path.get(i);}if (sum == targetSum)result.add(new ArrayList<>(path));return;}for (int i = startindex; i <= 9; i++) {path.add(i);// sum += i;backtracking(targetSum, k, i + 1);// sum -= i;path.removeLast();}}}


Topic2电话号码的字母组合

题目:

给定一个仅包含数字 2 2 2- 9 9 9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 1 1 不对应任何字母。
在这里插入图片描述

输入: d i g i t s = " 23 " digits = "23" digits="23"
输出: [ " a d " , " a e " , " a f " , " b d " , " b e " , " b f " , " c d " , " c e " , " c f " ] ["ad","ae","af","bd","be","bf","cd","ce","cf"] ["ad","ae","af","bd","be","bf","cd","ce","cf"]

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

1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, t e m p temp temp用来存放符合条件单一结果, l i s t list list用来存放符合条件结果的集合,与此同时我们需要建立一个数字到字符的映射,我们使用字符串数组 n u m S t r i n g numString numString 表示,还需要一个记录查到第几个第几个字符的索引 s t a r t i n d e x startindex startindex
所以整体代码如下:

// 设置全局列表存储最后的结果
List<String> list = new ArrayList<>();
// 每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的     
StringBuild StringBuilder temp = new StringBuilder();
void backtracking(String digits, String[] numString, int startindex)

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 (startindex == digits.length()) {// 查完最后一个字符,到达回溯出口list.add(temp.toString());return;
}

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

实现代码如下:

String str = numString[digits.charAt(startindex) - '0'];for (int i = 0; i < str.length(); i++) {temp.append(str.charAt(i));backtracking(digits, numString, startindex + 1);temp.deleteCharAt(temp.length() - 1);      }

完整的代码如下:

class Solution {List<String> list = new ArrayList<>();// 设置全局列表存储最后的结果// 每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuildStringBuilder temp = new StringBuilder();public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0)return list;// 初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""String[] numString = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };backtracking(digits, numString, 0);return list;}private void backtracking(String digits, String[] numString, int startindex) {if (startindex == digits.length()) {// 查完最后一个字符,到达回溯出口list.add(temp.toString());return;}// 得到digits[startindex]映射的字符串String str = numString[digits.charAt(startindex) - '0'];for (int i = 0; i < str.length(); i++) {temp.append(str.charAt(i));backtracking(digits, numString, startindex + 1);temp.deleteCharAt(temp.length() - 1);      }}
}

时间复杂度: O ( 3 m ∗ 4 n ) O(3^m * 4^n) O(3m4n),其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数
空间复杂度: O ( 3 m ∗ 4 n ) O(3^m * 4^n) O(3m4n)

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

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

相关文章

Docker----Dockerfile构建微服务镜像

目录 一、关键步骤 二、具体步骤 1、准备后端jar包(这里以java后端演示) 2、编写Dockerfile 3、构建镜像 4、运行镜像容器 5、测试是否成功 一、关键步骤 1、准备后端jar包(这里以java后端演示) 2、编写Dockerfile 3、构建镜像 4、运行镜像容器 5、测试是否成功 二…

阅读 - 二维码扫码登录原理

在日常生活中&#xff0c;二维码出现在很多场景&#xff0c;比如超市支付、系统登录、应用下载等等。了解二维码的原理&#xff0c;可以为技术人员在技术选型时提供新的思路。对于非技术人员呢&#xff0c;除了解惑&#xff0c;还可以引导他更好地辨别生活中遇到的各种二维码&a…

WebGIS之实现查询地区天气并让地区高亮

一.预览>> 二.思路>> 根据搜索框的内容来进行页面视角的切换&#xff0c;对应的地区高亮&#xff0c;右边有关天气的地方实时更新&#xff0c;并且因为代码体量非常小&#xff0c;并没有选择在框架下完成。直接一个html文件搞定了&#xff0c;但实际上还是有一些坑…

PMP的学习方法

PMBOK编撰了管理项目需要的49个过程&#xff08;输入、工具技术、输出&#xff09;。工具技术文件&#xff0c;林林总总百余个。第一部分&#xff0c;按照十大知识领域顺序从前到后编排&#xff1b;第二部分&#xff0c;按照五大过程组顺序重新编排了一遍。 一&#xff0c;PMB…

MySQL语法分类 DQL(2)条件查询

为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),math int,english int );insert into student (id,name,age,sex,address,math,english) values (1,马云,55,男,杭州,66,78),…

【开源】SpringBoot框架开发房屋出售出租系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…

STM32定时器预分频系数和自动重装载系数

现以一个图开始&#xff1a; 预分频器和计数器最大值都为65535&#xff08;从0开始&#xff09; 预分配器&#xff1a;比如输入的是72MHZ的频率&#xff0c;&#xff08;预分频系数为0&#xff09;不分频的话就是一秒数72000000次&#xff0c;如果预分频系数为&#xff08;72…

论文阅读——GeoChat(cvpr2024)

GeoChat : Grounded Large Vision-Language Model for Remote Sensing 一、引言 GeoChat&#xff0c;将多模态指令调整扩展到遥感领域以训练多任务会话助理。 遥感领域缺乏多模式指令调整对话数据集。受到最近指令调优工作的启发&#xff0c;GeoChat 使用 Vicuna-v1.5和自动化…

Java面向对象案例之描述专业和学生(4)

类的方法图 学生类&#xff1a; 属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;所学习的专业方法&#xff1a;学习的方法&#xff0c;描述学习状态。描述内容包括姓名、学号、年龄、所学习的专业信息 专业类&#xff1a; 属性&#xff1a;专业编号&#xf…

Day66:WEB攻防-Java安全SPEL表达式SSTI模版注入XXEJDBCMyBatis注入

目录 JavaSec搭建 Hello-Java-Sec搭建 Java安全-SQL注入-JDBC&MyBatis Java安全-XXE注入-Reader&Builder Java安全-SSTI模版-Thymeleaf&URL Java安全-SPEL表达式-SpringBoot框架 知识点&#xff1a; 1、Java安全-SQL注入-JDBC&MyBatis 2、Java安全-XXE注…

RabbitMQ学习总结-基础篇

1..RabbitMQ 本身是一个消息中间件&#xff0c;在服务应用中&#xff0c;可解决高性能&#xff0c;高并发&#xff0c;高应用的问题&#xff0c;极大程度上解决了应用的性能问题。 2.MQ的使用分为生产者和消费者&#xff0c;生产者生产消息&#xff0c;消费者去消费消息。 3.…

一瓶5.86万,听花酒什么来头?

听花酒&#xff0c;到底什么来头&#xff1f; 宣称有提升免疫力、改善睡眠、保障男性功能、调节生理紊乱、抗衰老等功效的听花酒&#xff0c;被315晚会曝光了。 相关话题词随即冲上了热搜。之后&#xff0c;售价最高达58600元的听花酒被京东、拼多多、淘宝等电商平台火速下架…