【代码随想录day22】【C++复健】77. 组合;216.组合总和III; 17.电话号码的字母组合

77. 组合

这题做完之后还是有一种稀里糊涂的感觉。思考了半天什么范围合理,并且怎么设置才能让这个范围合理,然而一看答案,发现答案完全没考虑这些因素,直接暴力全遍历了。只能说确实这样能够放弃思考,比较省心一些...

class Solution {
public:vector<vector<int>> combine(int n, int k) {vector<vector<int>> result;vector<int> path;int startindex = 1;select(n, k, startindex, result, path);return result;}void select(int n, int k, int startindex, vector<vector<int>>& result, vector<int>& path){for(int i=startindex; i<=n; i++){path.push_back(i);if(path.size() == k){result.push_back(path);}else{select(n, k, i+1, result, path);}path.pop_back();}}
};

重新看了下剪枝操作的视频部分,其实当时就是没想清楚到底是多少,看完之后才知道是n-(k-patch.size())+1,这里面patch.size()表示已经添加的元素,k-patch.size()代表还需要添加的元素,那么,n-(k-patch.size())+1就表示要从这里开始的索引。

关于为什么要+1其实有一个比较好想的点,就是从a到(a+k)一共有k+1个元素,所以当我们需要k个元素的时候,最晚要从a+1开始。

 216.组合总和III

在看完上题的解析后,本题我也是放弃了思考,但还是出现了两个小问题,都是因为没读题:

1 没看到要是k个数的和,以为是任意的

2 没看到只能是1-9,以为是任意的

class Solution {
public:vector<vector<int>> combinationSum3(int k, int n) {vector<vector<int>> result;vector<int> path;int startindex = 1;comb(k, n, startindex, result, path);return result;}void comb(int k, int n, int startindex, vector<vector<int>>& result, vector<int>& path) {if(n == 0 && path.size() == k){result.push_back(path);return ;}else if(n <0){return;}for(int i = startindex; i<=9; i++){path.push_back(i);n -= i;comb(k, n, i + 1, result, path);n += i;path.pop_back();}}
};
看完这个题的剪枝操作之后,发现有时候其实也需要把握一个度,比如卡哥写的剪枝逻辑是,如果当前的sum已经大于targetSum的话就可以返回,其实和我这个n<0是差不多一个意思的,都是比较好实现的剪枝逻辑。
但实际上,如果要进行最大程度的剪枝的话,比如说当前取i,还要取k个数,那么我的i+1一直到i+k如果已经大于sum了,就没必要继续了,这样其实是最效率最大程度的剪枝,但是有的时候代码实现的复杂程度也是要考虑的成本之一,尤其是像我这种懒人。

17.电话号码的字母组合

自己写了一段很蠢但是能执行的代码。

本来想的是用3*(电话按键-2)作为每段起点的,但是后来发现7和9还要做特殊处理,直接放弃了思考写出了如下代码。

class Solution {
public:vector<string> letterCombinations(string digits) {vector<string> s;string path;int i = 0;comb(digits, i, s, path);return s;}void comb(string digits, int curindex, vector<string>& s, string& path) {if(curindex == digits.size()){if(path != ""){s.push_back(path);}return ;}int now = digits[curindex]- '0';cout << now << endl;if(now == 2){for(int i = 0; i<3; i++){path += char('a' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 3){for(int i = 0; i<3; i++){path += char('d' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 4){for(int i = 0; i<3; i++){path += char('g' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 5){for(int i = 0; i<3; i++){path += char('j' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 6){for(int i = 0; i<3; i++){path += char('m' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 7){for(int i = 0; i<4; i++){path += char('p' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else if(now == 8){for(int i = 0; i<3; i++){path += char('t' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}else{for(int i = 0; i<4; i++){path += char('w' + i);comb(digits, curindex + 1, s, path);path.pop_back();}}}
};

在看完了卡哥的解析之后发现,二维数组确实是一个很好的存储方式,学到了。

用二维数组的话,就能避免像我的代码里一样不停地加加减减,只要正常用for循环遍历就行,更简单一点。

除此之外,还遇到了几个问题:
1 一开始判断条件写成了if(curindex == digits.size() - 1),然后报了一个栈溢出。这个为什么会导致栈溢出呢?当size是0的时候,等式右边是-1,但这个条件永远也达不到,因为curindex是永远不可能变成-1的,这就使得程序无线递归,直到发生栈溢出。

2 int now = digits[curindex] - '0';最开始没写后面的- '0';,导致实际上now的范围是从50开始的。实际上这里相当于是ascii码,需要减掉'0'对应的ascii码才是对的。

不过还有一个需要注意的一点,我修改的时候尝试了int(digits[curindex]),也不行,也输出的是ascii码。为什么不行呢?请看GPT:

也就是说实际上这个函数返回的也是ascii码。

3 不知道string怎么移除队尾元素,所以写了path -= char('j' + i);,但实际上string只重载了加号没有重载减号,所以这么写是会导致报错的。或者直接按照卡哥的写法,传参的时候这么传:

self.getCombinations(digits, index + 1, s + letter, result)

 这样子的话,就不用考虑怎么减去了,因为本来就没加进去。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

选择适合你的报表工具,山海鲸报表与Tableau深度对比

在数据分析和报表制作的领域&#xff0c;企业往往面临着选择合适工具的难题。尤其是当市场上有很多功能强大的工具时&#xff0c;如何从中挑选出最适合自己需求的报表软件成为了一个关键问题。今天&#xff0c;我们将对比两款报表工具——山海鲸报表和Tableau&#xff0c;看看它…

unity优化webgl下的textMeshPro字体大小

成果&#xff1a;优化前2.5M的字体文件优化后只有几百kb不到1m了 背景&#xff1a;unity微信小游戏要求字体文件在3m以内姑且我认为2.5m以内实际可以干到1M以内。微信小游戏要求尽可能的进游戏快&#xff0c;在这个背景下我们需要对字体进行优化&#xff0c;我采用的是3500字的…

Spark的学习-02

Spark Standalone集群的安装 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接客、资源管理和任务 调度&#xff0c;等同于YARN中的ResourceManager 从&#xff1a;Worker&#xff1a;计算节点&#xff1a;负责利用自己…

Vue前端框架

一.Vue概述 *Vue 是一套前端框架&#xff0c;用于免除原生JavaScript中的DOM 操作&#xff0c;简化书写。 *基于MVVM(Model-View-ViewModel)思想&#xff0c;实现数据的双 向绑定&#xff0c;将编程的关注点放在数据上。 *官网&#xff1a; https://cn.vuejs.org/ 二.Vue快速…

软件设计师 7日速成

数据流图和数据字典 数据流图 定义 数据流图是一种图形化的工具&#xff0c;用于描述系统中数据的流动情况。它可以帮助我们可视化数据在系统中的处理过程&#xff0c;包括数据的来源、去向、存储位置以及处理方式。 组成元素 数据流图通常包含以下四个基本元素&#xff1…

基于 Vue3、Vite 和 TypeScript 实现开发环境下解决跨域问题,实现前后端数据传递

引言 本文介绍如何在开发环境下解决 Vite 前端&#xff08;端口 3000&#xff09;和后端&#xff08;端口 80&#xff09;之间的跨域问题&#xff1a; 在开发环境中&#xff0c;前端使用的 Vite 端口与后端端口不一致&#xff0c;会产生跨域错误提示&#xff1a; Access to X…

【Allure】allure装饰器函数

**allure装饰器**​作用&#xff1a;用于将测试用例的数据展示到测试报告中 1.需要将这些装饰器函数添加**测试方法或测试类的开头**。2.同一个类或者一个方法可以添加多个装饰器函数 &#xff0c;这样此用例就具有了个作用属性 。 allure.epic() 敏捷中的概念 项目名称 allu…

python验证码滑块图像识别

文章目录 1、案例图片1、需求说明2、代码实现总结 1、案例图片 1、需求说明 python 3.10,写一个滑块验证码的自动化程序。需要一个opencv的函数&#xff0c;能准确的计算&#xff0c;在这同一张图片上&#xff0c;滑块形状和缺口形状的坐标位置及两个形状之间在X轴上的距离。请…

Linux基础-常用操作命令详讲

Linux基础-常用操作命令详讲 一、openssl加密简单介绍 1. 生成加密的密码散列&#xff08;password hash&#xff09;​编辑 1.1 常见的选项总结表 1.2 加密参数详解 2. 自签名证书 3. 证书转换 二、文件管理 1. 创建空文件 ​编辑 2. 删除文件 4. 新建目录 ​编辑…

【RAG系列】KG-RAG 用最简单的方式将知识图谱引入RAG

目录 前言 一、引入知识图谱的作用 二、引入知识图谱的挑战 三、KG-RAG的理论 query多跳有限性 知识局部密集性 四、KG-RAG的方法 向量入库 向量相似搜索 扩展子图 LLM Rerank LLM response 五、效果比对 六、源码 总结 前言 本文介绍一种比较新颖的RAG范式&am…

编程语言越来越多,为什么C/C++还没有被现在的时代淘汰呢?

近年来&#xff0c;随着人工智能、大数据等领域的兴起&#xff0c;各种新兴编程语言层出不穷&#xff0c;例如Python、Go等&#xff0c;它们以更简洁的语法、更丰富的库以及更友好的开发体验&#xff0c;吸引了大量开发者。 在这样的背景下&#xff0c;不少人开始质疑C/C这类“…

Docling:开源的文档解析工具,支持多种格式的解析和转换,可与其他 AI 工具集成

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

学习笔记:Spring框架源码Part.2——核心

学习视频链接&#xff1a;https://www.bilibili.com/video/BV1zd4y1L7YD Spring学习笔记——核心 前言第三章 容器和上下文一、认识bean工厂1、基础能力2、更强的枚举能力3、灵活的分层能力4、构建和自动装配的能力5、更强的配置能力6、更多配置项7、工厂的生命周期 二、bean工…

linux守护进程与后台进程的区别

守护进程与后台进程有以下区别&#xff1a; 1. 概念与定义 后台进程&#xff1a; 是指在操作系统后台运行的进程&#xff0c;它不与用户直接交互&#xff08;没有连接到用户的终端&#xff09;。用户在终端中启动一个程序并让其在后台运行&#xff08;如通过在命令后加“&…

【360】基于springboot的志愿服务管理系统

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装志愿服务管理系统软件来发挥其高效地信息处理的作用&#x…

【LLM Agents体验】Dify框架的安装指南

Dify简介&#xff1a; 核心功能‌12 ‌Dify是一款开源的大语言模型(LLM)应用开发平台&#xff0c;融合了后端即服务&#xff08;Backend as a Service, BaaS&#xff09;和LLMOps的理念&#xff0c;使开发者可以快速搭建生产级的生成式AI应用。LLMOps涵盖了大型语言模型的开发、…

TODO Error occurred while trying to proxy:【】

文章目录 场景异常解决 场景 使用 Ant Disign Pro 连接本地接口。 异常 Error occurred while trying to proxy: localhost:8000/api/login/account?token%20%20123[HPM] Error occurred while proxying request localhost:8000/api/login/account?token%20%20123 to http…

Linux 文件基本属性

1.Linux 文件基本属性 Linux 系统是一种典型的多用户系统&#xff0c;不同用户处于不同地位&#xff0c;拥有不同的权限。为了保护系统的安全性&#xff0c;Linux 系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。Linux 通常使用以下两…

数据结构-归并排序笔记

【数据结构】八大排序(超详解附动图源码)_数据结构排序-CSDN博客 看这个学思路 一 归并排序介绍: 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法&#xff0c;该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解&#xf…

关于使用python pptx生成或“复制”PPT页面的问题

先说两个结论&#xff1a; 对于主题不完全相同的页面&#xff0c;pptx 无法完全复制PPT页面&#xff0c;文字图片可以复制&#xff0c;但是背景之类的无法复制pptx 无法直接在指定页码或者指定页面后插入页面 今天做项目的时候&#xff0c;需要根据PPT模板使用python生成相应…