当前位置: 首页 > news >正文

【代码随想录训练营第42期 Day23打卡 回溯Part2 - LeetCode 39. 组合总和 40.组合总和II 131.分割回文串

目录

一、做题心得

二、题目与题解

题目一:39. 组合总和

题目链接

题解:回溯

题目二:40.组合总和II

题目链接

题解:回溯

题目三:131.分割回文串

题目链接

题解:回溯

三、小结


一、做题心得

今天是代码随想录打卡的第23天,来到了回溯章节的part2。今天共完成了三道打卡题,分别是组合问题的延续以及分割回文串的经典问题。整体来说,今天的题还是有些比较新颖的地方,尤其是一些需要注意的点,等下会慢慢提到。

好了,话不多说,直接开始今天的内容。

二、题目与题解

题目一:39. 组合总和

题目链接

39. 组合总和 - 力扣(LeetCode)

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates = [2,3,6,7], 
target = 7输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], 
target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], 
target = 1
输出: []

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40
题解:回溯

这个题和昨天打卡做的 216. 组合总和 III - 力扣(LeetCode)基本一致,这里唯一的区别就是这道题允许同一个数字多次使用。怎样考虑到多次使用同一个数的情况呢?其实我们只需要改变递归状态就可以了--我们知道,递归在这里等价于纵向遍历,只要我们每次递归的时候都再次从当前开始的位置进行,那么就考虑到了多次使用同一个数的情况:

 backtrack(candidates,target,i); 每次递归都从i再次开始。(注意与216题区分)

代码如下(注意我个人习惯用ans表示结果数组,vec表示临时(当前)数组):

class Solution {
public:vector<vector<int>> ans;vector<int> vec;void backtrack(vector<int>& candidates,int target,int start) {      //回溯函数:注意start参数的定义--实现递归必不可少的部分int sum = 0;        //用来统计当前选取元素之和for (int i = 0; i < vec.size(); i++) {sum += vec[i];}if (sum == target) {ans.push_back(vec);return;}if (sum > target) {     //(注意)剪枝:当前选取元素求和大于目标值,则无需继续添加元素,返回递归return;}for (int i = start; i < candidates.size(); i++) {vec.push_back(candidates[i]);backtrack(candidates,target,i);       //不用i+1了,表示可以重复读取当前的数(与不能重复的题相区分)vec.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {backtrack(candidates,target,0);return ans;}
};

题目二:40.组合总和II

题目链接

40. 组合总和 II - 力扣(LeetCode)

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

示例 1:

输入: candidates = [10,1,2,7,6,1,5],target = 8
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30
题解:回溯

这个题的话,看上去和之前两个题差不多,也是组合求和问题,所以我们依然可以套用之前的模板。不过需要注意的是,题目中 candidates 数组中可能存在重复的数字,而每个数字不能重复使用,最重要的是,要满足解集不能包含重复的组合--这个就将是这个题的关键(即如何实现去重)。

我们首先要搞清楚一个概念:回溯过程就像是树的遍历搜索--for循环对应树的横向操作(即针对某一层),递归则对应着树的纵向遍历(即针对一条的分支,一个路线)。

我们去重,需要的是解集不能包含重复的组合(即多个组合之间的问题),而不是某个组合不能出现同样的元素--这就需要我们考虑横向操作,即不能在同一层中出现相同的元素。(这可能不是很好理解,就是纵向操作(递归)是解决的一个组合里边的问题,横向操作(for循环)是解决多个组合之间的问题)

其他部分和之前的题差不多,应该问题不大,这里我们直接看代码:

class Solution {
public:vector<vector<int>> ans;vector<int> vec;void backtrack(vector<int>& candidates, int target, int start) {int sum = 0;for (int i = 0; i < vec.size(); i++) {sum += vec[i];}if (sum == target) {ans.push_back(vec);return;}if (sum > target) {    //剪枝操作return;}for (int i = start; i < candidates.size(); i++) {if (i > start && candidates[i] == candidates[i - 1]) {      //横向操作:跳过重复元素--注意理解:这里跳过的是同一个树层重复的元素(横向看),而不是某一个组合中重复的元素(纵向看--每一个组合都是由不同树层元素构成的)continue;       //跳过同一树层使用过的元素}  vec.push_back(candidates[i]);backtrack(candidates, target, i + 1);       //纵向操作(不同树层):递归遍历得到各种组合vec.pop_back();}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {sort(candidates.begin(), candidates.end());     //先对 candidates 进行排序:排序后则重复元素相邻backtrack(candidates, target, 0);return ans;}
};

题目三:131.分割回文串

题目链接

131. 分割回文串 - 力扣(LeetCode)

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 

回文串

 。返回  s 所有可能的分割方案。

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成
题解:回溯

这个题相对前两道难度就要大一点了。

我们先回顾下回文串的判断:双指针。这个没记错的话,应该是刚开始那几天打卡的内容吧,现在看来已经很简单了。通过定义左右指针一个从头遍历,一个从尾遍历,比较对应的字符,若一致,则左指针右移,右指针左移,继续遍历,直到结束;若不一致,则不是回文串。

这道题的话,个人认为主要的难点在于终止条件的书写以及如何将子串分割出来并做判断--判断是否为回文串。

这里我们先引入一个函数:substr

s.substr(pos, len):表示截取字符串 s 从 start 开始往后长度为 len 的子串

这样我们就能够通过递归得出字符串的所有子串,并挨个判断是否是回文串了。

这样终止条件也就好确定了:即到达递归调用的终点,此时vec存放满足的字符串组合

代码如下:

class Solution {
public:vector<vector<string>> ans;vector<string> vec;bool isHuiWen(string str) {         //判断字符串是否为回文子串:简单双指针int left = 0;int right = str.size() - 1;while (left < right) {if (str[left] != str[right]) {return false;}else {left++;right--;}}return true;}void backtrack(string s, int start) {if (start == s.size()) {        //终止条件:到达递归调用的终点  ans.push_back(vec);  return;  }  for (int i = start; i < s.size(); i++) {  string substring = s.substr(start, i - start + 1);      //截取从start到i的子串 if (isHuiWen(substring)) {          //如果当前子串是回文,则加入当前划分,并继续向后搜索  vec.push_back(substring);  backtrack(s, i + 1);     //注意start在递归调用过程中不断变化的,它代表了当前正在考虑的子串的起始位置vec.pop_back();  }  }  }  vector<vector<string>> partition(string s) {backtrack(s, 0);return ans;}
};

三、小结

今天的打卡到此也就结束了,重点学习了回溯的实现过程。最后,我是算法小白,但也希望终有所获。

相关文章:

【代码随想录训练营第42期 Day23打卡 回溯Part2 - LeetCode 39. 组合总和 40.组合总和II 131.分割回文串

目录 一、做题心得 二、题目与题解 题目一&#xff1a;39. 组合总和 题目链接 题解&#xff1a;回溯 题目二&#xff1a;40.组合总和II 题目链接 题解&#xff1a;回溯 题目三&#xff1a;131.分割回文串 题目链接 题解&#xff1a;回溯 三、小结 一、做题心得 今天是代码随想录…...

书生.浦江大模型实战训练营——(三)Git基本操作与分支管理

最近在学习书生.浦江大模型实战训练营&#xff0c;所有课程都免费&#xff0c;以关卡的形式学习&#xff0c;也比较有意思&#xff0c;提供免费的算力实战&#xff0c;真的很不错&#xff08;无广&#xff09;&#xff01;欢迎大家一起学习&#xff0c;打开LLM探索大门&#xf…...

数据可视化Axure大屏原型制作分享

数据可视化大屏通过清晰、直观且易于理解的方式呈现大量复杂数据&#xff0c;已成为各行各业中不可或缺的工具。Axure作为一款功能强大的原型设计工具&#xff0c;为数据可视化大屏的制作提供了强大的支持和丰富的资源。 Axure RP 是一款强大的原型设计工具&#xff0c;非常适…...

Python3安装

更新镜像&#xff1a; yum -y install epel-release.noarch 1.安装Python3 [root18 ~]# yum -y install python3 2.查看版本&#xff1a; [root18 ~]# python3 --version Python 3.6.8 3.执行镜像包&#xff1a; pip3 install -i https://pypi.tuna.tsinghua.edu.cn/sim…...

基于Python的数据科学系列(4):函数

引言 在前几篇文章中&#xff0c;我们探讨了Python中的基本数据类型、列表、元组和字典。在本文中&#xff0c;我们将深入研究Python中的函数。函数是编程中非常重要的概念&#xff0c;它允许我们将代码组织成模块化、可重用的组件。通过学习如何定义和使用函数&#xff0c;我们…...

高频焊接设备配电系统无源滤波系统的设计

1、高频焊机系统谐波状况简介 变压器容量&#xff1a;S11-M-1600/10KVA&#xff08;105%&#xff09;/0.4KV 短路阻抗&#xff1a;3.9% 谐波负载情况&#xff1a;一台600KW高频焊接设备 型号&#xff1a;GGP600-0.3-HC 输入电压&#xff1a;380V 输出电压&#xff1a;0…...

模拟退火的

题目链接 体验乱调参数而看天意的奇特体验 #include<bits/stdc.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pii; const int inf0x3f3f3f3f; const int N1e510; const int mod1e97; //#define int long…...

为什么有的地方笔记本经常连不上wifi,而手机可以?

mm&#xff1a;程程&#xff0c;为什么我的笔记本在图书馆&#xff0c;老是连不上wifi&#xff1f;经常要手工连好几次&#xff0c;我的手机却没有这样的问题。 我&#xff1a;你先用手机热点连一下&#xff0c;我给你远程看一下吧。 mm&#xff1a;好了&#xff0c;我的远程代…...

组件化开发

iOS的组件化开发是一种将大型应用拆分成多个独立、可复用的组件的开发模式。每个组件负责完成特定的功能&#xff0c;并通过明确定义的接口与其他组件进行交互。这种开发模式有助于提高代码的可维护性、可读性和可扩展性&#xff0c;同时降低模块之间的耦合度。 组件化开发的概…...

java学习--文件

简介 文件,对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文 件,excel文件 ... 都是文件。它既可以保存一张图片,也可以保持视频,声音 …. 文件流 常用的文件操作 创建文件的对象相关构造器和方法 示范 方式一&#xff1a; 方式二&#xff1a; 老师演示…...

k8s—Prometheus+Grafana+Altermaneger构建监控平台

目录 一、安装node-exporter 1.下载所需镜像 2.编写node-export.yaml文件并应用 3.测试node-exporter并获取数据 二、Prometheus server安装和配置 1.创建sa(serviceaccount)账号&#xff0c;对sa做rabc授权 1&#xff09;创建一个 sa 账号 monitor 2&#xff09;把 sa …...

Dijkstra算法求解最短路径 自写代码

#include <iostream> #define Max 503 #define INF 0xcffffffusing namespace std;typedef struct AMGraph { //定义图int vex, arc;int arcs[Max][Max]; //邻接矩阵 };int dist[Max], path[Max]; //dis保存最短路径总权值、path通过保存路径的前驱结…...

C#如何对某个词在字符串中出现的次数进⾏计数(LINQ)

文章目录 基础知识实现方法基础计数LINQ优化处理标点符号总结 LINQ&#xff08;Language-Integrated Query&#xff09;是C#和VB.NET中强大的查询语言&#xff0c;它可以用来查询集合、SQL数据库、XML文档等。在C#中&#xff0c;我们可以使用LINQ来简化对字符串中特定单词出现次…...

Linux篇之OS层内核参数的调优

Linux内核参数调优 Linux 内核参数的调优和分类是一个复杂的主题&#xff0c;这涉及到系统性能、稳定性和安全性等多个方面。 内核参数主要可以分为以下几类&#xff1a; 1. 内核参数的分类 1.1 系统性能参数 这些参数影响系统的整体性能&#xff0c;包括 CPU 调度、内存管理…...

DLMS/COSEM中的信息安全:安全密钥(上)

加密密钥是一个参数,和加密算法一起使用,加密算法决定了这样一种方式,带有密钥的实体,可以重现和进行逆操作,而没有密钥则不能。对DLMS/COSEM的用途,操作的例子包含: ——明文转换成密文; ——密文转换成明文; ——计算和验证认证码(MAC); …...

Taro基础知识学习

一、安装及使用 CLI工具安装 需要使用 npm 或者 yarn 全局安装 tarojs/cli //使用 npm 安装 CLI npm install -g tarojs/cli//使用 yarn 安装 CLI yarn global add tarojs/cli//使用 cnpm 安装 CLI cnpm install -g tarojs/cli//使用npm info查看Taro的版本信息 npm info ta…...

浮点型在内存中的存储

前言 在上一期中我们讲到了有关于整型在内存中的存储&#xff0c;新朋友可以点开&#x1f517;了解一下&#xff0c;那这一期中我们将讲到的浮点数是不是存储方式和整型一致呢&#xff1f; 一、浮点数在内存中的存储 为了探究这个问题我们先来看一段代码 #include<stdio…...

微信小程序之behaviors

目录 概括 Demo演示 进阶演示 1. 若具有同名的属性或方法 2. 若有同名的数据 3. 若有同名的生命周期函数 应用场景 最后 属性&方法 组件中使用 代码示例&#xff1a; 同名字段的覆盖和组合规则 概括 一句话总结: behaviors是用于组件间代码共享的特性, 类似一…...

java.lang.NoClassDefFoundError: ch/qos/logback/core/util/StatusPrinter2

1、问题 SpringBoot升级报错&#xff1a; Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/util/StatusPrinter2 类找不到&#xff1a; Caused by: java.lang.ClassNotFoundException: ch.qos.logback.core.util.StatusPrinter22、…...

WebRTC ICE配置类型

ICE&#xff08;Interactive Connectivity Establishment&#xff09;是一个用于建立WebRTC和其他实时通信会话中的点对点连接的框架。ICE协议通过尝试多个候选地址&#xff08;候选者&#xff09;来寻找最佳路径来连接两个对等端。ICE有多种配置类型&#xff0c;包括标准ICE、…...

制造知识普及(八)--企业内部物料编码(IPN)与制造商物料编码(MPN)

1、什么是物料编码 通常情况下&#xff0c;物料编码分两种&#xff0c;一种是企业内部物料编码&#xff08;IPN&#xff09;&#xff0c;由于在企业研发制造和生产中确认物料唯一性的&#xff0c;用于承载设计参数要求和技术要求。另一种是制造商物料编码&#xff08;MPN&…...

大模型学习笔记 - InstructGPT中的微调与对齐

LLM 微调 之 InstructGPT中的微调与对齐 LLM 微调 之 InstructGPT中的微调与对齐 技术概览 InstructGPT中的微调与对齐 大体步骤标注数据量模型训练 1. SFT 是如何训练的2. Reward Model是如何训练的3. RLHF 是如何训练的具体讲解RLHF 的loss 函数 模型效果参考链接&#xf…...

Unity近似的Transform实现

Unity近似的Transform实现 #include <stdint.h> #include<iomanip> #include <sstream>#include "Transform.h"//Transform::Transform(const Transform& a){ // LOGW("xww 2"); //}Transform::Transform(glm::vec3 localPositio…...

openvidu私有化部署

openvidu私有化部署 简介 OpenVidu 是一个允许您实施实时应用程序的平台。您可以从头开始构建全新的 OpenVidu 应用程序&#xff0c;但将 OpenVidu 集成到您现有的应用程序中也非常容易。 OpenVidu 基于 WebRTC 技术&#xff0c;允许开发您可以想象的任何类型的用例&#xf…...

基于深度学习的视频伪造检测

基于深度学习的视频伪造检测旨在利用深度学习技术来检测和识别伪造的视频内容。伪造视频&#xff0c;尤其是深伪&#xff08;Deepfake&#xff09;视频&#xff0c;近年来随着生成对抗网络&#xff08;GAN&#xff09;技术的发展&#xff0c;变得越来越逼真和难以识别。这对个人…...

python机器人编程——开发一个pymatlab工具箱(上)

目录 一、前言二、实现过程2.1 封装属性2.2 数据流化显示2.3 输入数据的适应性 三、核心代码说明3.1 设置缓存3.2 随机信号3.3 根据设置绘图 五、总结四、源码PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源 一、前言 我们知道m…...

输入类控件

目录 1.Line Edit 代码示例: 录入个人信息 代码示例: 使用正则表达式验证输入框的数据 代码示例: 验证两次输入的密码一致 代码示例: 切换显示密码 2.Text Edit 代码示例: 获取多行输入框的内容 代码示例: 验证输入框的各种信号 3.Combo Box 代码示例: 使用下拉框模拟…...

C++20中的模块

大多数C项目使用多个翻译单元(translation units)&#xff0c;因此它们需要在这些单元之间共享声明和定义(share declarations and definitions)。headers的使用在这方面非常突出。模块(module)是一种language feature&#xff0c;用于在翻译单元之间共享声明和定义。它们是某些…...

Selenium与流行框架集成:pytest与Allure报告

Selenium与流行框架集成&#xff1a;pytest与Allure报告 在现代软件开发中&#xff0c;自动化测试是确保产品质量和快速迭代的关键。Selenium作为业界领先的Web自动化测试工具&#xff0c;其灵活性和强大的功能受到广泛认可。为了进一步提升测试效率和报告质量&#xff0c;本文…...

日撸Java三百行(day17:链队列)

目录 一、队列基础知识 1.队列的概念 2.队列的实现 二、代码实现 1.链队列创建 2.链队列遍历 3.入队 4.出队 5.数据测试 6.完整的程序代码 总结 一、队列基础知识 1.队列的概念 今天我们继续学习另一个常见的数据结构——队列。和栈一样&#xff0c;队列也是一种操…...