代码学习记录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<>();// 设置全局列表存储最后的结果
    // 每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild
    StringBuilder 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.mfbz.cn/a/464128.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

维基百科推广秘诀13个方法助你成为行业领导者-华媒舍

维基百科&#xff08;Wikipedia&#xff09;作为全球最大、最权威的在线百科全书&#xff0c;拥有海量的知识内容&#xff0c;被广大用户广泛使用。对于任何一个领域的从业者来说&#xff0c;建立自己的维基百科页面&#xff0c;无疑是提升行业影响力的重要手段。本文将向您介绍…

LEETCODE 100255. 成为 K 特殊字符串需要删除的最少字符数

整体思路: 1.可以看到这道题是要求是最小的&#xff0c;那么可以想到遍历所有情况 2.把题干已知条件转换为一个数组&#xff0c;那么只需要以数组每个元素为开头遍历所有情况即可。 3.对于一个数考虑其后面的情况&#xff0c;其后每个数等于这个数k和数本身的最小值(遍历累计求…

【C语言】指针基础知识(一)

计算机上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数据也会放回内存中。 一,内存和地址 内存被分为一个个单元&#xff0c;一个内存单元的大小是一个字节。 内存单元的编号&#xff08;可以理解为门…

Ypay源支付2.8.8免授权聚合免签系统

本帖最后由 renleixiaoxu 于 2024-3-15 09:46 编辑 产品介绍 XPay是专为个人站长打造的聚合免签系统&#xff0c;拥有卓越的性能和丰富的功能。采用全新轻量化的界面UI&#xff0c;让您可以更加方便快捷地解决 知识付费和运营赞助的难题。同时&#xff0c;它基于高性能的Thin…

ubuntu安装docker的详细教程

检查卸载老版本docker ubuntu下自带了docker的库&#xff0c;不需要添加新的源。 但是ubuntu自带的docker版本太低&#xff0c;需要先卸载旧的再安装新的。 注&#xff1a;docker的旧版本不一定被称为docker&#xff0c;docker.io 或 docker-engine也有可能&#xff0c;所以卸…

Hypermesh碰撞安全之头部撞击模拟

1、首先到自定义工作面板中选择Engineering Solutions(工程解决方案&#xff09; 2、进入行人保护建模流程模块 3、导入所需要的模型 4、对模型进行切割&#xff0c;选择所需要保留的区域 5、单击next进入下一界面 6、选择打击类型 下一步进入&#xff1a; 这样就完成了打击点…

基于深度学习的唇语识别系统的设计与实现

概要 人工智能作为三大工程之一&#xff0c;从上个世纪至今仍然活跃于各个行业的研究与应用之中&#xff0c;应时代的热潮方向&#xff0c;本 课题主要针对深度学习技术应用于唇语识别当中&#xff0c;实现词语唇语的翻译功能。唇语识别在图像处理中一直是一个富 有挑战性的课题…

基础知识学习 -- qnx 系统

QNX是一个基于优先级抢占的系统。 这也导致其基本调度算法相对比较简单。因为不需要像别的通用操作系统考虑一些复杂的“公平性”&#xff0c;只需要保证“优先级最高的线程最优先得到 CPU”就可以了。 基本调度算法 调度算法&#xff0c;是基于优先级的。QNX的线程优先级&a…

【LabVIEW FPGA入门】单周期定时循环

单周期定时循环详解 单周期定时环路是FPGA编程中最强大的结构之一。单周期定时循环中的代码更加优化&#xff0c;在FPGA上占用更少的空间&#xff0c;并且比标准While循环中的相同代码执行得更快。单周期定时环路将使能链从环路中移除&#xff0c;以节省FPGA上的空间。…

C++算法学习心得八.动态规划算法(4)

1.零钱兑换&#xff08;322题&#xff09; 题目描述&#xff1a; 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬币的数量是无限的。…

QTextToSpeech的使用——Qt

前言 之前随便看了几眼QTextToSpeech的帮助就封装使用了&#xff0c;达到了效果就没再管了&#xff0c;最近需要在上面加功能&#xff08;变换语速&#xff09;&#xff0c;就写了个小Demo后&#xff0c;发现不对劲了。 出现的问题 场景 写了个队列添加到语音播放子线程中&a…

多线程(代码案例: 单例模式, 阻塞队列, 生产者消费者模型,定时器)

设计模式是什么 类似于棋谱一样的东西 计算机圈子里的大佬为了能让小菜鸡的代码不要写的太差 针对一些典型的场景, 给出了一些典型的解决方案 这样小菜鸡们可以根据这些方案(ACM里面叫板子, 象棋五子棋里叫棋谱, 咱这里叫 设计模式), 略加修改, 这样代码再差也差不到哪里去 … …

官方安装配置要求服务器最低2核4G

官方安装配置要求服务器至少2核、4G。 如果服务器低于这个要求&#xff0c;就没有必要安装&#xff0c;因为用户体验超级差。 对于服务器CPU来说&#xff0c;建议2到4核就完全足够了&#xff0c;太多就浪费了&#xff0c;但是内存越大越好&#xff0c;最好是4G以上。 如果服务器…

数据库 | Mysql - [binlog]

INDEX 1 什么是 binlog2 作用3 数据恢复4 主从复制 1 什么是 binlog Mysql server 的日志文件 自动开启 2 作用 数据恢复主从复制 3 数据恢复 实际场景 01.00&#xff1a;数据全量备份08.00&#xff1a;数据丢失&#xff08;比如被人误删&#xff09;09.00&#xff1a;故…

贪心问题题目集一(代码 注解)

目录 介绍&#xff1a; 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 题目四&#xff1a; 题目五&#xff1a; 题目六&#xff1a; 题目七&#xff1a; 题目八&#xff1a; 介绍&#xff1a; 贪心算法是一种特殊的算法思想&#xff0c;它在每一步选择中都采取…

二叉树的初步学习和顺序结构实现

当我们学完顺序表、链表、栈和队列的时候&#xff0c;我们就要开始学习树了。树对于以后的学习有非常大的帮助&#xff0c;尤其是排序。好了&#xff0c;开始我们的学习吧。 1.树的概念及结构 1.1树的结构 树结构是一种非线性结构。它是由n&#xff08;n>0&#xff09;个…

ISIS接口MD5 算法认证实验简述

默认情况下&#xff0c;ISIS接口认证通过在ISIS协议数据单元&#xff08;PDU&#xff09;中添加认证字段&#xff0c;例如&#xff1a;MD5 算法&#xff0c;用于验证发送方的身份。 ISIS接口认证防止未经授权的设备加入到网络中&#xff0c;并确保邻居之间的通信是可信的。它可…

【教学类-34-10】20240313 春天拼图(Midjounery生成线描图,4*4格拼图块)(AI对话大师)

作品展示&#xff1a; 背景需求&#xff1a; 利用华文彩云空心字&#xff08;粗胖字体。凑满9个拼图&#xff09;制作了3*3的拼图块 【教学类-34-09】20240310华文彩云学号拼图&#xff08;3*3格子浅灰底图 深灰拼图块&#xff09;&#xff08;AI对话大师&#xff09;-CSDN博…

唯一约束

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 唯一约束 唯一约束的特点是在某一个列上的内容不允许出现重复。 例如&#xff0c;现在要收集用户的信息&#xff0c;假设包含编号&#xff08;mid&#xff09;、姓名&…