【代码随想录算法训练营第二十七天|39. 组合总和、40.组合总和II、131.分割回文串】

news2024/9/25 9:37:52

代码随想录算法训练营第二十七天|39. 组合总和、40.组合总和II、131.分割回文串

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

题解参考y总的:http://www.acwing.com

39. 组合总和

我是一看就会,一写就废。先看代码:

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        dfs(candidates,target,0);
        return res;
    }

    void dfs(vector<int>& candidates,int target,int n)
    {
        if(target == 0)
        {
            res.push_back(path);
            return;
        }
        if(n == candidates.size()) return;
        for(int i = 0;candidates[n] * i <= target;i++)
        {
            dfs(candidates,target - candidates[n]*i,n + 1);
            path.push_back(candidates[n]);
        }
        for(int i = 0;candidates[n] * i <= target;i++)
        {
            path.pop_back();
        }

    }
};

这道题目使用模板,关键在两点,一个是递归结束条件,一个是递归过程。首先是递归的结束条件,递归的结束条件就是和前面组合||一样,当target为0的时候,就结束。然后递归的过程,因为这里每个的元素是无限重复选取的,所以使用 i * candidates[n],这里n代表下标为n的元素。

40.组合总和II

看代码:

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;

    vector<vector<int>> combinationSum2(vector<int>& c, int target) {
        sort(c.begin(),c.end());
        dfs(c,target,0);
        return res;
    }

    void dfs(vector<int>& c,int target,int n)
    {
        if(!target)
        {
            res.push_back(path);
            return;
        }
        if(n == c.size()) return;
        int k = n + 1;
        while(k < c.size() && c[k] == c[n]) k++;
        int cnt = k - n;
        for(int i = 0;c[n] * i <= target && i <= cnt;i++)
        {
            dfs(c,target - c[n] * i,k);
            path.push_back(c[n]);
        }
        for(int i = 0;c[n] * i <= target && i <= cnt;i++)
        {
            path.pop_back();
        }
    }
}; 

和第一个一样,只不过这里的元素变成有限个数了,所以首先要统计元素个数,这里借鉴的y的,先从小到大排个序,然后统计一个元素重复的个数,还是使用candidates[n] * i,只要i不超过限制的个数就可以。还可以使用hash表来记录元素的个数。

131.分割回文串

看代码:

class Solution {
public:
    vector<vector<bool>> f;
    vector<vector<string>> res;
    vector<string> path;
    vector<vector<string>> partition(string s) {
        int n = s.size();
        f = vector<vector<bool>>(n,vector<bool>(n));
        for(int j = 0;j < n;j++)
        {
            for(int i = 0;i <= j;i++)
            {
                if(i ==j) f[i][j] = true;
                else if(s[i] == s[j])
                {
                    if(i + 1 > j - 1 || f[i + 1][j - 1]) f[i][j] = true;
                }
            }
        }
        dfs(s,0);
        return res;

    }

    void dfs(string s,int n)
    {
        if(n == s.size()) res.push_back(path);
        else
        {
            for(int i = n;i < s.size();i++)
            {
                if(f[n][i])
                {
                    path.push_back(s.substr(n,i - n + 1));
                    dfs(s,i + 1);
                    path.pop_back();
                }
            }
        }
    }
};

首先要判断一个字串是不是回文,首先第一种方法可以使用双指针的方法,一个从头开始,一个从尾开始,只要每次向中间走都字符都相同,那就是回文。
还有一种方法是:(下图来自acwing截图)
在这里插入图片描述首先判断i到j串,第i位和第j位是相同的字符,然后第i+1和第j-1也是回文,这就用的是递归,第一个方法用的是迭代。
f就是用来记录从第i到j位是否是回文串的。首先先构造f,如果是i==j,也就是单个字母,单个字母肯定的是回文;然后判断s[i]和s[j]是否相等,如果相等,再判断一下,如果是i + 1 > j - 1(也就是就只有两个字母),因为之前已经判断了s[i] == s[j]了,所以就两个字母肯定是回文;或者f[i + 1][j - 1]也是回文,那i到j就是回文。
构建好回文记录表f之后,开始走模板第一步,判断条件,什么时候才算一轮的结果,那必须是所有字母都走过一遍的时候,才是加入一个path的时候,然后然后i从n开始,i每次向后走,每次都判断一下n到i是否是回文,如果是的话就加入答案中。
回到一个地方:有人可能注意到,递归的时候dfs后面是i+1,而不是n+1,我个人认为是如果是n+1的话,因该就已有一条路径了,因为每次递归下去,再回溯到开始的时候,就是最开始的n,它就不变了,最后答案中估计也就一条正确答案,比如aab,可能答案只有:[[“a”,“a”,“b”]]其他没有了,因为回溯到开始n不变了。也就是说如果是n+1,外面的for循环相当于没有作用。
在这里插入图片描述

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

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

相关文章

第1章-计算机网络基础

目录 1. 计算机网络与计算机 2. 计算机网络的定义和基本功能 2.1. 定义&#xff1a;计算机网络是一组自治计算机互连的集合 2.2. 基本功能 2.3. 计算机网络的演进 2.4. 广域网(Wide Area Network&#xff0c;WAN) 2.5. 网络的拓扑结构 2.6. 数据交换方式 2.7. 衡量计算…

R语言中数据框是什么?

在数据分析过程中离不开表格&#xff0c;通常使用Excel来做数据分析&#xff0c;行和列用来存放不同的数据&#xff0c;表格能清晰直观的展示数据&#xff0c;而且可以将多张表组合联系起来&#xff0c;这种不约而同的规范也同样适用于R语言。 R语言中的数据框&#xff08;Data…

C#winform上位机开发学习笔记7-串口助手的波特率参数设置功能添加

1.功能描述 上位机与下位机进行通讯时需要用到波特率设置功能&#xff0c;以及尝试与下位机实体进行通讯。 2.代码部分 步骤1&#xff1a;串口开启按钮事件中添加代码 serialPort1.BaudRate Convert.ToInt32(comboBox14.Text, 10);//将十进制的文本转换为32位整型赋值给串…

计算机网络-OSI参考模型(来由 通信过程 各层分析)

文章目录 总览OSI模型怎么来的&#xff1f;OSI参考模型OSI参考模型解释通信过程各层分析应用层表示层会话层传输层网络层数据链路层物理层 小结 总览 两种网络分层结构 结合事实标准和法定标准得到一个中和版本5层的体系结构 OSI模型怎么来的&#xff1f; 刚开始各个公司的…

图像处理之《用于统一源跟踪和深度伪造检测的深度可分离水印SepMark》论文精读

一、文章摘要 恶意的Deepfakes导致了一场关于区分真脸和伪造脸的激烈冲突。尽管已经制定了许多事后检测Deepfakes的对策&#xff0c;但毫无疑问&#xff0c;在可预见的操作之前&#xff0c;被动取证没有考虑对原始人脸采取任何预防措施。为了完成这个取证生态系统&#xff0c;…

Git Docker 学习笔记

注意&#xff1a;该文章摘抄之百度&#xff0c;仅当做学习笔记供小白使用&#xff0c;若侵权请联系删除&#xff01; 目录 列举工作中常用的几个git命令&#xff1f; 提交时发生冲突&#xff0c;你能解释冲突是如何产生的吗&#xff1f;你是如何解决的&#xff1f; git的4个…

【VUE】如何有效管理重复请求

【VUE】如何管理重复请求 需求 重复的HTTP请求可能对应用程序性能造成很大影响&#xff0c;尤其是在用户快速点击或多次触发同一操作时。在Vue应用中&#xff0c;我们可以使用axios的请求拦截器&#xff08;interceptors&#xff09;配合AbortController来取消重复的HTTP请求…

【漏洞复现】CloudPanel makefile接口远程命令执行漏洞(CVE-2023-35885)

文章目录 前言声明一、CloudPanel 简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 CloudPanel 是一个基于 Web 的控制面板或管理界面&#xff0c;旨在简化云托管环境的管理。它提供了一个集中式平台&#xff0c;用于管理云基础架构的各个方面&#xff0c;包括 &a…

【开源】基于JAVA语言的新能源电池回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…

k8s集群异常恢复

前提、我自己的k8s采用的是单master节点两个从节点部署&#xff0c;我针对单master情况进行恢复说明 场景一&#xff1a;正常开关虚拟机&#xff0c;可直接重启kubelet进行恢复 1、1、一般重启后三个节点都需要检查&#xff0c;输入命令检查kubelet&#xff1a; systemctl s…

计算机网络-TCP/IP模型及五层参考模型(OSI与TCP/IP相同点 不同点 5层参考模型及数据封装与解封装)

文章目录 OSI与TCP/IPOSI与TCP/IP相同点OSI与TCP/IP不同点5层参考模型5层参考模型的数据封装与解封装小结 OSI与TCP/IP OSI&#xff1a;先理论&#xff0c;但没有实践 TCP/IP&#xff1a;先实践&#xff0c;再理论 TCP/IP&#xff1a;基于协议栈而分层 网络接口层&#xff1a;…

IDEA 2023.3.2 安装教程

1.下载2023.3.2版本IDEA 链接&#xff1a;https://pan.baidu.com/s/1RkXBLz6qxsd8VxXuvXCEMA?pwd5im6 提取码&#xff1a;5im6 2.安装 3.解压文件&#xff0c;进入&#xff0c;选择方式3 4.将下面文件夹复制到任意位置&#xff08;不要有中文路径&#xff09; 5.进入下面文…

CmakeList教程

一、CmakeList介绍&#xff1a; cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译 二、CmakeList的常用指令 1.指定…

DevOps系列文章之 GitLab Runner

Runner Runner就像一个个的工人&#xff0c;而Gitlab-CI就是这些工人的一个管理中心&#xff0c;所有工人都要在Gitlab-CI里面登记注册&#xff0c;并且表明自己是为哪个工程服务的。当相应的工程发生变化时&#xff0c;Gitlab-CI就会通知相应的工人执行软件集成脚本。如下图所…

优维全面可观测产品能力分解①:架构可观测

2023年&#xff0c;基于客户需求的洞察&#xff0c;历经1年的潜心优化&#xff0c;优维在第四季度推出集大成产品——「全面可观测解决方案」&#xff0c;涵盖架构可观测、故障可观测、变更可观测、用户可观测、应用服可观测、资源可观测、运维状态可观测等不同场景的可观测能力…

使用 Vector 在 Kubernetes 中收集日志

多年来&#xff0c;我们一直在使用 Vector 在我们的 Kubernetes 平台中收集日志&#xff0c;并成功地将其应用于生产中以满足各种客户的需求&#xff0c;并且非常享受这种体验。因此&#xff0c;我想与更大的社区分享它&#xff0c;以便更多的 K8s 运营商可以看到潜力并考虑他们…

Multisim14.0仿真(三十八)基于74ls190的电子计时器设计

一、仿真原理图&#xff1a; 二、仿真效果&#xff1a; 三、时钟源按所需调整。

[python]使用pyqt5搭建yolov8钢筋计数一次性钢材计数系统

【官方框架地址】 github地址&#xff1a;https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8是一种先进的深度学习模型&#xff0c;用于目标检测和识别。在钢筋计数任务中&#xff0c;Yolov8可以有效地识别和计数图像中的钢筋。下面是对如何使用Yolov8实现钢筋…

一本满是错误的Go语言书,凭什么1000万人都在读

犯错是每个人生活的一部分。正如爱因斯坦曾说过&#xff1a;一个从未犯过错的人从未尝试过新东西。 最重要的不是我们犯了多少错误&#xff0c;而是我们从错误中学到了多少东西。 这个观点同样适用于编程领域。 我们从一门编程语言中获取经验不是一个神奇的过程&#xff0c;…

Rocky Linux 8.9 安装图解

风险告知 本人及本篇博文不为任何人及任何行为的任何风险承担责任&#xff0c;图解仅供参考&#xff0c;请悉知&#xff01;本次安装图解是在一个全新的演示环境下进行的&#xff0c;演示环境中没有任何有价值的数据&#xff0c;但这并不代表摆在你面前的环境也是如此。生产环境…