【算法练习Day22】 组合总和 III电话号码的字母组合

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 组合总和 III
    • 剪枝
  • 电话号码的字母组合
  • 总结:

组合总和 III

216. 组合总和 III - 力扣(LeetCode)

组合总和3和上一期的组合思路上差不太多,用数字1-9相当于上一道组合题的1-n的范围求解答案,而这道题多了一个要想加等于一个固定的数值。

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(int targetSum,int k,int sum,int startIndex){if(path.size()==k){if(sum==targetSum){result.push_back(path);}}for(int i=startIndex;i<=9;i++){sum+=i;path.push_back(i);backtracking(targetSum,k,sum,i+1);sum-=i;path.pop_back();}}vector<vector<int>> combinationSum3(int k, int n) {result.clear();path.clear();backtracking(n,k,0,1);return result;}
};

我们直接向数组里加入数据,因为我们暂时不能确定怎样的组合才能凑够n,所以我们当数组里元素等于k个数据时,直接判断一下,如果此时总和等于我们想要的答案,那么直接加入答案数组,否组向上一层直接返回。而下面的单层递归逻辑是我们仍然用一个start作为开始的下标来记录避免取到重复下标,将1-9每一个数都加入进来试错,直到找出正确答案。

剪枝

这道题也同样存在可以剪枝的部分,这道题可以分成两部分的剪枝,也很巧妙。

第一部分的剪枝原因在于这道题是组合求和,它给出了一个相加之和为n的组合,这个时候我们可以判定当我们此时递归的时候,sum当前组合内的值,如果大于了给定的目标值n,那么很明显我们一定要return了,因为是在1-9中取数,都是正数,怎么加也不可能找的到了。所以第一部分剪枝一定是写在判断部分的代码里,这和上一期的组合是有所区别的。

相似的剪枝是第二部分的剪枝, 仍然是采用之前的做法剪枝,path.size()是当前数组中所存的数据有几个,k-path.size()是还需要几个数字,9-(k-path.size())+1,是我们最多可以从哪个数字向下进行递归,这里的数是从1-9的,不是从数组中取数,最开始不是0而是1,所以要加1。

class Solution {
public:
vector<vector<int>>result;
vector<int>path;
void backtraking(int k,int n,int start,int sum){if(sum>n) return;if(path.size()==k)if(sum==n){result.push_back(path);return;}for(int i=start;i<=9-(k-path.size())+1;i++){path.push_back(i);backtraking(k,n,i+1,sum+i);path.pop_back();}
}vector<vector<int>> combinationSum3(int k, int n) {backtraking(k,n,1,0);return result;}
};

个人认为的缺陷

第一部分的剪枝是为了避免当sum>n时候继续递归,第二部分剪枝是告诉最多从哪里开始递归,第二部分的剪枝是完全根据传进答案的个数做的剪枝,与最终结果n无关。

那么当n=100时候,k=2时候我们还是无法快速的判断当前是无法找的出正确的答案的,看到这里可能会去想,如果是这种情况还是能很快的判断啊,通过第二次剪枝很快就根据k跳出递归了,那如果n很大,k也很大,但是k大也不足以凑出n呢?那还是会进行很多次递归-回溯的过程吧,做了很多次的搜索但是却一个结果都无法返回,但是好像暂时也没有其他什么方法能够比它更好用了。

电话号码的字母组合

17. 电话号码的字母组合 - 力扣(LeetCode)

这道题也是组合题,不过略有一些难度。首先我们要根据它给出的电话按键,用map或者数组将其数值所对应的字母都保存起来。然后再构思回溯函数,同样的也是创建一个结果数组,创立一个中间存数据的数组。这里我们并不需要像start一样作用的变量来指示我们下一次要走向哪一个下标,因为这里我们是同时操作多个数组,往里面加入数据,我们需要的是一个变量告诉我们该遍历哪一个电话按键了它指向的是传进来的电话号码序列的下标。

由于这样的缘故,所以我们结束条件可以确定是该变量等于函数传进来的电话号码字符串的字符个数,这里有一些疑问,为什么我们这个这个变量是表示下标你还要它等于字符序列总个数呢?而不是总序列个数减一,原因是我们在遍历到最后一个字符时我们仍然需要将最后一个数字对应的字母排列进来,而不是直接跳出循环,所以我们要等待它这个下标指向最后一个字符的下一个时候,才能来做判断。当它与字符序列的个数相等时我们收获结果,并想上一层返回,以寻求其他结果。

class Solution {
public:string lettermap[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};vector<string> result;string s;void backtracking(const string& digits,int index){if(index==digits.size()){result.push_back(s);return;}int digit=digits[index]-'0';string letters=lettermap[digit];for(int i=0;i<letters.size();i++){s.push_back(letters[i]);backtracking(digits,index+1);s.pop_back();}}vector<string> letterCombinations(string digits) {s.clear();result.clear();if(digits.size()==0){return result;}backtracking(digits,0);return result;}
};

这里有一些需要我们注意的,我们要在循环内创立一个整形来存储该字符序列的某个位置它所代表的数字是什么,然后才是用另一个字符串变量来记录该数字所对应的字母序列,我们仅需要一个变量来指示下标的原因在上面已经说过了,而当它返回到上一层之后,我们如何找到上一次对应的电话号码的字母的下一位呢?这是递归返回后i++所要做的事情,我们完全不需要担心,其他的单层逻辑和那些组合题大体一样,不做赘述。

总结:

今天我们完成了组合总和 III\电话号码的字母组合两道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

力扣环形链表(1)进阶环形链表(2)及环形链表的约瑟夫问题

为了加深对环形链表的理解和掌握&#xff0c;这两道题是很不错的选择。 这里所说环形链表不是一个圈圈的结构&#xff0c;而是带环链表。 链接&#xff1a;环形链表&#xff08;1&#xff09; 注意这里链表的长度 所以要注意链表是否为空 第一种方法&#xff0c;应该是比较容易…

大数据 DataX 详细安装教程

目录 一、环境准备 二、安装部署 2.1 二进制安装 2.2 python 3 支持 三、Data X 初体验 3.1 配置示例 3.1.1. 生成配置模板 3.1.2 创建配置文件 3.1.3 运行 DataX 3.1.4 结果显示 3.2 动态传参 3.2.1. 动态传参的介绍 3.2.2. 动态传参的案例 3.3 迸发设置 …

【传输层协议】UDP/TCP结构特点与原理(详解)

文章目录 1. UDP1.1 UDP结构1.2 UDP特点1. 无连接2. 不可靠3. 面向数据报4. 缓冲区5. 大小受限6. 无序性 2. TCP2.1 TCP结构2.2 TCP特点1. 有连接2. 可靠性3. 面向字节流4. 拥塞控制5. 头部开销 2.3 TCP原理1. 确认应答&#xff08;安全机制&#xff09;2. 超时重传&#xff08…

基于springboot实现家具网站设计与实现平台项目【项目源码+论文说明】

摘要 随着移动互联网技术的深入发展&#xff0c;电子商务也不断的完善&#xff0c;线上销售额不断提高&#xff0c;网络消费成为人民日常生活的一部分。并且随着电子商务的发展&#xff0c;也呈现出多元化方向&#xff0c;各种农村电商、生鲜电商、家具电商等&#xff0c;带动…

java SpringBoot基础

目录 SpringBootWeb快速入门前言需求开发步骤创建SpringBoot工程&#xff08;需要联网&#xff09;定义请求处理类运行测试 HTTP协议HTTP概述HTTP-请求协议格式GET方式的请求协议POST方式的请求协议 HTTP-响应协议格式HTTP-协议解析 WEB服务器-Tomcat简介基本使用注意事项 Spri…

新增Node.js运行环境、新增系统缓存清理功能,1Panel开源面板v1.7.0发布

2023年10月16日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.7.0版本。 在这个版本中&#xff0c;1Panel新增Node.js运行环境&#xff1b;新增系统缓存清理功能&#xff1b;应用安装时支持选择远程数据库。此外&#xff0c;我们进行了40多项功能更新和…

apk和小程序渗透

apk和小程序域服务器通信使用的还是http协议&#xff0c;只是使用了加密。只要可以获取到http的请求报文&#xff0c;就可以回归到web渗透的层面。apk和小程序的渗透很复杂&#xff0c;涉及逆向时要进行脱壳&#xff0c;脱壳后反编译了&#xff0c;源代码没做加密就能直接逆向出…

阵列信号处理_对比常规波束形成法(CBF)和Capon算法

空间谱估计 利用电磁波信号来获取目标或信源相对天线阵列的角度信息的方式&#xff0c;也称测向、波达方向估计&#xff08;DOA&#xff09;。主要应用于雷达、通信、电子对抗和侦察等领域。 发展 常规波束形成&#xff08;CBF&#xff09;。本质是时域傅里叶变换在空域直接…

排序算法-基数排序法(RadixSort)

排序算法-基数排序法&#xff08;RadixSort&#xff09; 1、说明 基数排序法与我们之前讨论的排序法不太一样&#xff0c;并不需要进行元素之间的比较操作&#xff0c;而是属于一种分配模式排序方式。 基数排序法比较的方向可分为最高位优先&#xff08;Most Significant Di…

centos 里面的service自启动app.jar,出现两个java进程,app是同一个端口

当使用jps -lv查看java虚拟机进程 app.jar启动后&#xff0c;居然出现两个启动进程&#xff0c;而且他们的端口都一样&#xff0c;同一端口&#xff0c;是不允许启动两个相同app的。 使用进程ps查看进程工具 #ps -aux 参数说明&#xff1a; a: 显示跟当前终端关联的所有进…

做web自动化测试遇到Chrome浏览器老是自动更新,怎么办 ? 这里提供两个解决办法 。

web自动化安装驱动安装 进行web自动化时 &#xff0c;需要提前安装浏览器的驱动 &#xff0c;尤其是chrome浏览器 。它的更新速度很快 &#xff0c;是不是更新了新版本 。这就导致我们的驱动也要跟着变化。 1.停止自动更新 那么 &#xff0c;如何关闭chrome浏览器的自动更新…

6.6 图的应用

思维导图&#xff1a; 6.6.1 最小生成树 ### 6.6 图的应用 #### 主旨&#xff1a;图的概念可应用于现实生活中的许多问题&#xff0c;如网络构建、路径查询、任务排序等。 --- #### 6.6.1 最小生成树 **概念**&#xff1a;要在n个城市中建立通信联络网&#xff0c;则最少需…