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

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

一、参考资料

组合总和

题目链接/文章讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html

视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ

组合总和II

题目链接/文章讲解:https://programmercarl.com/0040.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CII.html

视频讲解:https://www.bilibili.com/video/BV12V4y1V73A

分割回文串

题目链接/文章讲解:https://programmercarl.com/0131.%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2.html

视频讲解:https://www.bilibili.com/video/BV1c54y1e7k6

二、LeetCode39. 组合总和

https://leetcode.cn/problems/combination-sum/description/

给你一个 无重复元素 的整数数组 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

本题搜索的过程抽象成树形结构如下:

注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!

而在77.组合 (opens new window)216.组合总和III (opens new window)中都可以知道要递归K层,因为要取k个元素的组合。

我也能自己写出代码啦,模板真香

class Solution {
private:vector<int> path;vector<vector<int>> res;void backtracking(vector<int> candidates, int target, int sum, int startIndex) {if (sum > target) return ;if (sum == target) {res.push_back(path);return ;}for (int i = startIndex; i < candidates.size(); i++) {sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, sum, i);  // 不用i+1了,表示可以重复读取当前的数path.pop_back();sum -= candidates[i];}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {backtracking(candidates, target, 0, 0);return res;}
};

剪枝优化(这里没有详细研究,大体思路还是在循环的地方提前终止):

对总集合排序之后,如果下一层的sum(就是本层的 sum + candidates[i])已经大于target,就可以结束本轮for循环的遍历

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum == target) {result.push_back(path);return;}// 如果 sum + candidates[i] > target 就终止遍历for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, sum, i);sum -= candidates[i];path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();sort(candidates.begin(), candidates.end()); // 需要排序backtracking(candidates, target, 0, 0);return result;}
};

在求和问题中,排序之后加剪枝是常见的套路!

三、LeetCode40.组合总和II

https://leetcode.cn/problems/combination-sum-ii/description/

给定一个候选人编号的集合 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

先排序!再树层去重

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过

  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {if (sum == target) {result.push_back(path);return;}for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {// used[i - 1] == true,说明同一树枝candidates[i - 1]使用过// used[i - 1] == false,说明同一树层candidates[i - 1]使用过// 要对同一树层使用过的元素进行跳过if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {continue;}sum += candidates[i];path.push_back(candidates[i]);used[i] = true;backtracking(candidates, target, sum, i + 1, used); // 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次used[i] = false;sum -= candidates[i];path.pop_back();}}public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool> used(candidates.size(), false);path.clear();result.clear();// 首先把给candidates排序,让其相同的元素都挨在一起。sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return result;}
};

我写的如下~

class Solution {
private:vector<int> path;vector<vector<int>> res;void backtracking(vector<int> candidates, int target, int sum, int startIndex, vector<bool> used) {if (sum > target) return ;if (sum == target) {res.push_back(path);return ;}for (int i = startIndex; i < candidates.size(); i++) {if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) continue;sum += candidates[i];used[i] = true;path.push_back(candidates[i]);backtracking(candidates, target, sum, i + 1, used);path.pop_back();used[i] = false;sum -= candidates[i];}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool> used(candidates.size(), false);sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return res;}
};

四、LeetCode131.分割回文串

https://leetcode.cn/problems/palindrome-partitioning/description/

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。

示例 1:
输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a" 输出:[["a"]]

提示:
1 <= s.length <= 16
s 仅由小写英文字母组成

带注释版:

class Solution {
private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int startIndex) {// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex >= s.size()) {result.push_back(path);return;}for (int i = startIndex; i < s.size(); i++) {if (isPalindrome(s, startIndex, i)) {   // 是回文子串// 获取[startIndex,i]在s中的子串string str = s.substr(startIndex, i - startIndex + 1);path.push_back(str);} else {                                // 不是回文,跳过continue;}backtracking(s, i + 1); // 寻找i+1为起始位置的子串path.pop_back(); // 回溯过程,弹出本次已经填在的子串}}bool isPalindrome(const string& s, int start, int end) {for (int i = start, j = end; i < j; i++, j--) {if (s[i] != s[j]) {return false;}}return true;}
public:vector<vector<string>> partition(string s) {result.clear();path.clear();backtracking(s, 0);return result;}
};

优化后的代码就没详细学了

我能自己写出这个题的代码,已经觉得自己真的进步很大了:

class Solution {
private:vector<string> path;vector<vector<string>> res;bool isPalinedromic(string s, int begin, int end) {for (int i = begin, j = end; i < j; i++, j--) {if (s[i] != s[j]) return false;}return true;}void backtracking (string s, int startIndex) {if(startIndex > s.size()) return ;if (startIndex == s.size()) {res.push_back(path);return ;}for(int i = startIndex; i < s.size(); i++) {if(isPalinedromic(s, startIndex, i)) {string str = s.substr(startIndex, i - startIndex + 1);path.push_back(str);} else continue;backtracking(s, i + 1);path.pop_back();}}
public:vector<vector<string>> partition(string s) {backtracking(s, 0);return res;}
};

今日总结:

题目确实是当天写完的,只是博客没有及时写

  1. 感觉到自己真的进步好多了,能够理解懂视频的题目讲解,经历一些debug后还能尝试控制时间的前提下独立完成代码。

  1. 今天的难点应该挺多的,我花了很多时间理解来着,讲解回文串分割的视频应该看了两遍。

  1. 另外今天的组合数一个不太容易想到题解的“去重”问题,也是挺困扰,希望真的掌握后能做到举一反三呢

继续加油哈小赵~

相关文章:

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

一、参考资料组合总和题目链接/文章讲解&#xff1a;https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1KT4y1M7HJ 组合总和II题目链接/文章讲解&#xff1a;https://programmercarl.com/004…...

vueday01-脚手架安装详细

一、vue脚手架安装命令npm i -g vue/cli 或 yarn global add vue/cli安装上面的工具&#xff0c;安装后运行 vue --version &#xff0c;如果看到版本号&#xff0c;说明安装成功或 vue -V工具安装好之后&#xff0c;就可以安装带有webpack配置的vue项目了。创建项目之前&#…...

初识cesium3d(一)

使用ViteVue3.2Cesium。Vite需要Node.js版本14.18及以上版本。Vite命令创建的工程会自动生成vite.config.js文件&#xff0c;来配置一些相关的参数。 1、使用Vite创建vue3项目 # npm npm init vitelatest cesium-app -- --template vue # yarn yarn create vite cesium-app…...

点云转3D网格【Python】

推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 在本文中&#xff0c;我将介绍我的 3D 表面重建过程&#xff0c;以便使用 Python 从点云快速创建网格。 你将能够导出、可视化结果并将结果集成到您最喜欢的 3D 软件中&#xff0c;而无需任何编码经验。 此外&#xff0…...

【OpenCV图像处理系列一】OpenCV开发环境的安装与搭建(Ubuntu + Window都适用)

&#x1f517; 运行环境&#xff1a;OpenCV&#xff0c;Ubuntu&#xff0c;Windows &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x…...

【代码随想录】-动态规划专题

文章目录理论基础斐波拉契数列爬楼梯使用最小花费爬楼梯不同路径不同路径 II整数拆分不同的二叉搜索树背包问题——理论基础01背包二维dp数组01背包一维数组&#xff08;滚动数组&#xff09;装满背包分割等和子集最后一块石头的重量 II目标和一和零完全背包零钱兑换 II组合总和…...

c++数据类型 输入输出

C++语法 //常用包: iostream:cin cout endl cstdio:scanf printf algorithm:max min reverse swap cstring:memset memcpymemset(a,-1,sizeof a) 填充数组memcpy(b,a,sizeof a) 将a数组复制到b数组,长度是a数组字节长度 cmath:sin sqrt pow abs fabs编程是一种控制计…...

【设计模式-11】责任链模式

认识设计模式&#xff08;十一&#xff09;---责任链模式【一】责任链模式【二】介绍&#xff08;1&#xff09;意图&#xff08;2&#xff09;主要解决&#xff08;3&#xff09;何时使用&#xff08;4&#xff09;如何解决&#xff08;5&#xff09;关键代码&#xff08;6&am…...

SpringBoot+Vue实现智能物流管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…...

【MT7628】MT7628如何修改串口波特率、调试串口物理口、使用UART3口

环境说明 sdk版本:Mediatek_ApSoC_SDK_4320_20150414.tar.bz2 芯片方案:MT7628A Uboot修改串口波特率方法 修改rt2880.h文件 修改include/configs/rt2880.h文件CONFIG_BAUDRATE宏的值 - #define CONFIG_BAUDRATE 57600 +#define CONFIG_BAUDRATE 115200 Kernel中修改串口波特…...

css盒模型介绍

在使用CSS进行网页布局时&#xff0c;我们一定离不开的一个东西————盒子模型。盒子模型&#xff0c;顾名思义&#xff0c;盒子就是用来装东西的&#xff0c;它装的东西就是HTML元素的内容。或者说&#xff0c;每一个可见的 HTML 元素都是一个盒子&#xff0c;下面所说的盒子…...

onetab 谷歌插件历史数据清除

文章目录方法1&#xff1a;测试也可以步骤1&#xff1a;批量执行点击步骤2&#xff1a;python 脚本模拟点击确定操作方法2&#xff1a;成功【推荐】步骤1&#xff1a;修改confirm&#xff0c;类似于hook操作步骤2&#xff1a;批量点击删除操作&#xff1a;onetab 谷歌插件历史数…...

GRBL源码简单分析

结构体说明 GRBL里面的速度规划是带运动段前瞻的&#xff0c;所以有规划运动段数据和微小运动段的区分 这里的“规划运动段”对应的数据结构是plan_block_t&#xff0c;前瞻和加减速会使用到&#xff0c;也就是通过解析G代码后出来的直接直线数据或是圆弧插补出来的拟合直线数据…...

第一部分:简单句——第一章:简单句的核心——二、简单句的核心变化(谓语动词的情态)

二、简单句的核心变化 简单句的核心变化其实就是 一主一谓&#xff08;n. v.&#xff09; 表达一件事情&#xff0c;谓语动词是其中最重要的部分&#xff0c;谓语动词的变化主要有四种&#xff1a;三态加一否&#xff08;时态、语态、情态、否定&#xff09;&#xff0c;其中…...

软考高级考试中有五大证书,其中哪个更值得考?

计算机软考属于专业技术人员职业资格水平评价类&#xff0c;是职业资格、专业技术资格&#xff08;职称&#xff09;和专业技术水平"三合一"的考试&#xff0c;是目前IT行业仅有的国家级考试。考试不受学历、专业、资历等条件限制。软考高级考试中有五大证书&#xf…...

FlexRay™ 协议控制器 (E-Ray)-04

网络管理 累积的网络管理 (NM) 向量位于网络管理寄存器 1 到网络管理寄存器 3 (NMVx (x = 1-3)) 中。【The accrued Network Management (NM) vector is located in the Network Management Register 1 to Network Management Register 3 (NMVx (x = 1-3)).】 网络管理向量 x…...

container_of 根据成员变量获得包含其的对象的地址!

写在前面 本系列文章的灵感出处均是各个技术书籍的读后感&#xff0c;详细书籍信息见文章最后的参考文献 CONTAINER_OF 在书中发现一个很有意思的宏&#xff0c;以此可以衍生出来其很多的用法&#xff0c;这个宏可以根据某个成员变量的地址得到包含这个成员变量地址的对象的…...

Linux进程概念

Linux进程概念前言冯诺依曼体系操作系统设计操作系统的目的如何理解OS是一款搞“管理”的软件&#xff1f;系统调用和库函数的概念进程的概念描述进程组织进程查看进程fork&#xff08;&#xff09;前言 本篇博客主要介绍一些&#xff1a;冯诺依曼体系、OS的理解、进程的一些概…...

算法设计与分析

两个例子:调度问题与投资问题 例1&#xff1a;调度问题 问题 有 n 项任务&#xff0c;每项任务加工时间已知.从 0时刻开始陆续安排到一台机器上加工. 每个任务的完成时间是从 0 时刻到任务加工截止的时间. 求: 总完成时间&#xff08;所有任务完成时间之和&#xff09;最短…...

C++ 基础

命名空间 在 C/C 中&#xff0c;变量、函数和类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff0c;namespace 关键字的…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...