代码随想录第23天|回溯part3 组合与分割

39.组合总和

在这里插入图片描述

class Solution {
public:vector<vector<int>> res;vector<int> path;void backTracking(vector<int>& candidates,int target,int sum,int n,int step){if(n > 150) return;if(sum > target) return;if(sum == target){res.push_back(path);return;}for(int i = step; i < candidates.size(); i++){path.push_back(candidates[i]);backTracking(candidates,target,sum+candidates[i],n+1,i);path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {backTracking(candidates,target,0,0,0);return res;}
};

40.组合总和2

在这里插入图片描述
难题
在这里插入图片描述
可以看出在candidates[i] == candidates[i - 1]相同的情况下:
used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
used[i - 1] == false,说明同一树层candidates[i - 1]使用过
因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。
而 used[i - 1] == true,说明是进入下一层递归,去下一个数,所以是树枝上

即:因为在排序后,相同的数都会挨在一起,如果当前数和上个数相同的话,那么在递归的过程中,如果上一个数没被用到,那么当前数肯定是一种重复的情况,因为这两个数相同,肯定是先使用前一个数的,而如果上一个没用到,则表示是已经递归过上一个数的所有情况并回溯了,现在递归下一个数的,所以需要跳过重复的这个数。

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

也可以直接使用startIndex来去重,每层递归里,如果一个数和上一个数相同,则跳过

void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum == target) {result.push_back(path);return;}for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {// 要对同一树层使用过的元素进行跳过// 这里i > startIndex是为了确保可以选取到同一种元素,在下层递归的时候,因为传入的是i+1,所以如果i+1和上一个元素相同,递归后也可以选取和i相同的元素if (i > startIndex && candidates[i] == candidates[i - 1]) {continue;}sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, sum, i + 1); // 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次sum -= candidates[i];path.pop_back();}}

131.分割回文串

在这里插入图片描述
回溯三步
1.递归函数确定参数:string s, int step
2.确定终止条件:因为分割串类似于组合问题,
例如对于字符串abcdef:
组合问题:选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中再选取第三个…。
切割问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中再切割第三段…。
在这里插入图片描述
返回条件就是,当切割点超过串的长度时,说明已经找到一种每个字串都是回文串的方案了,这个时候就可以把字串数组传给结果
3.确定单层逻辑
单层逻辑就是树的横向遍历,即用for循环确定切割点,且切割点必须不断往后

class Solution {
public:vector<vector<string>> res;vector<string> path;bool check(string t) {for (int i = 0, j = t.size() - 1; i < j; i++, j--) {if (t[i] != t[j])return false;}return true;}void backTracking(string s, int step) {if (step >= s.size()) {// 如果大于数组长度,则找到一组全为回文串的字串组合,否则被continue掉了res.push_back(path);return;}for (int i = step; i < s.size(); i++) {// 截取字串string t = s.substr(step, i - step + 1);// 找到了符合条件的字串if (check(t))path.push_back(t);elsecontinue;// 进行下一层递归backTracking(s, i + 1);path.pop_back();}}vector<vector<string>> partition(string s) {backTracking(s, 0);return res;}
};

最近在学go,所以提供一个go版本的代码

var res [][]string
var path []stringfunc check(t string) bool {for i, j := 0, len(t)-1; i < j; i, j = i+1, j-1 {if t[i] != t[j] {return false}}return true
}
func backTracking(s string, step int) {if step >= len(s) {temp := make([]string, len(path))copy(temp, path)res = append(res, temp)return}for i := step; i < len(s); i++ {t := s[step : i+1]if check(t) {path = append(path, t)} else {continue}backTracking(s, i+1)path = path[:len(path)-1]}
}
func partition(s string) [][]string {path = make([]string, 0)res = make([][]string, 0)backTracking(s, 0)return res
}

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

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

相关文章

Scikit-Learn随机森林分类

Scikit-Learn随机森林分类 1、随机森林分类1.1、随机森林分类概述1.2、随机森林分类的优缺点2、Scikit-Learn随机森林分类2.1、Scikit-Learn随机森林分类API2.2、Scikit-Learn随机森林分类初体验(葡萄酒分类)2.3、Scikit-Learn随机森林分类实践(鸢尾花分类)2.4、参数调优与…

微信支付(可复用)

3.1微信支付 本项目选择小程序支付 参考&#xff1a;产品中心 - 微信支付商户平台微信支付商户平台提供各类支付产品满足商家通过微信支付收款的需求&#xff1b;平台提供智慧经营&#xff0c;现金红包&#xff0c;代金券等运营工具&#xff0c;助力商家更好的玩转营销&#x…

FCA-数知鸟 试题及答案

第1题【判断题】文档不可以设置层级关系 A. 正确B. 错误 正确答案&#xff1a;B 第2题【判断题】文档批量创建需求功能可以一次性创建不同类型的需求 A. 正确B. 错误 正确答案&#xff1a;B 第3题【判断题】甘特图中可以根据实际需要添加表格的显示字段&#xff0c;不可添加甘…

程序员应该有什么职业素养?

程序员的六大职业素养&#xff1a;构建成功职业生涯的基石 在不断变化的技术世界中&#xff0c;程序员不单要保持技术的锋利&#xff0c;也需要培养相应的职业素养&#xff0c;这些素养在很大程度上决定了一个程序员的职业生涯能否走得长远。以下是我认为最为重要的六大职业素…

C++ 20新特性之Concepts

C20的新特性之一Concepts&#xff0c;为C的模板编程带来了重大的改进和便利。以下是关于C20中Concepts特性的详细介绍&#xff1a; 基本概念 定义&#xff1a;Concepts是C20中引入的一种新的语言特性&#xff0c;用于限制类和函数模板的模板类型和非类型参数。它允许你为模板编…

LLM基础知识

LLM背景知识介绍 1 大语言模型 (LLM) 背景 大语言模型 (英文&#xff1a;Large Language Model&#xff0c;缩写LLM) 是一种人工智能模型, 旨在理解和生成人类语言. 大语言模型可以处理多种自然语言任务&#xff0c;如文本分类、问答、翻译、对话等等。 &#x1f4a5;通常&…

golang中2个只定义不需要初始化的高效字符缓存类型 bytes.Buffer和strings.Builder使用示例

在golang中&#xff0c;有2个高效的用于字符数据写入的缓存类型&#xff0c;同时他们也都实现了io.Writer接口&#xff0c;一个是bytes包中的Buffer 这个还实现了io.Reader接口&#xff1b; 另外一个是 strings包中的字符串构建类型 Builder。 在使用他们的时候是不需要初始化的…

gpedit.msc找不到文件

新建文件gpedit.bat内容如下,以管理员身份运行 echo off pushd "%~dp0" dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-…

NVIDIA - QPU

转载自 What Is a QPU? ( 2022 年 7 月 29 日 里克梅里特 https://blogs.nvidia.com/blog/what-is-a-qpu/ 文章目录 一、概述二、那么&#xff0c;什么是 QPU&#xff1f;三、量子处理器如何工作&#xff1f;四、制作量子比特的多种方法五、光的量子比特六、简单的芯片&#x…

git commit使用husky校验代码格式报错,没有将钩子 ‘.huskypre-commit‘ 设置为可执行,钩子被忽略。

使用git提交代码时&#xff0c;通过husky校验代码格式&#xff0c;终端报错 因为没有将钩子 .husky/pre-commit 设置为可执行 系统&#xff1a;Mac husky 在 Windows 上能够正常运行 解决办法 # 没有权限就给个权限 使用 chmod x 给权限 # 通过这行命令解决husky钩子不执行…

【C#】类和结构体的区别

目录 1.区别概述 ​编辑 2.细节区别 3.结构体的特别之处 4.如何选择结构体和类 1.区别概述 结构体和类的最大区别是在存储空间上&#xff0c;前者是值类型&#xff0c;存储在栈上&#xff0c;后者是引用类型&#xff0c;存储在堆上&#xff0c;它们在赋值上有很大的区别&a…

【C++入门到精通】C++ thread线程库 [ C++入门 ]

阅读导航 引言一、thread类的简单介绍二、thread类的用法1. 创建线程2. 使用 Lambda 表达式3. 传递参数给线程4. 线程的 join 和 detach5. 检查线程是否可 join6. 线程的 ID7. 线程的移动语义8. 线程的析构&#x1f6a8; 注意事项 三、线程函数参数温馨提示 引言 C thread线程…

实现流程化办公,可以相信拖拽表单设计器!

当前&#xff0c;竞争压力越来越大&#xff0c;利用什么样优良的办公软件实现流程化办公&#xff1f;可以一起来了解低代码技术平台、拖拽表单设计器的优势特点&#xff0c;看看它们是如何助力企业降本、增效、提质的。低代码技术平台的优势特点多&#xff0c;可以助力企业用拖…

Uni app 开发支付宝小程序,保存到相册,获取小程序权限列表失败问题记录及解决方案。

第一种实现方案思路&#xff1a;先获取所有用户的权限列表配置&#xff0c;进行判断是否可以访问相册。 我在做的时候&#xff0c;在测试环境可以获取权限列表&#xff0c;但是在正式环境就会报错&#xff0c;报错原因是获取不到当前用户的权限列表用的这个方法&#xff08;uni…

Jtti:租用的php服务器运行异常是什么原因导致的?

PHP服务器运行异常可能由多种原因引起。以下是一些常见问题及其相应的解决方案&#xff1a; 1. 服务器资源不足 原因&#xff1a; CPU、内存或磁盘空间不足&#xff0c;导致服务器性能下降。 解决方案&#xff1a; 检查系统资源&#xff1a;使用以下命令检查CPU、内存和磁盘使用…

轻松实现微信内下载,Xinstall让你的App推广更高效!

在微信中推广App&#xff0c;你是否遇到过这样的困扰&#xff1a;推广链接被微信拦截&#xff0c;用户需要手动复制链接到浏览器才能下载&#xff0c;大大降低了安装率&#xff1f;今天&#xff0c;我们要介绍的Xinstall&#xff0c;就是一款能够解决这一痛点的神器&#xff01…

2.2 OpenCV随手简记(三)

图像的阈值处理定义 &#xff1a;将图像转化为二值图像&#xff08;黑白图&#xff09;, 也可以用于彩色图形&#xff0c;达到夸张的效果 目的&#xff1a;是用来提取图像中的目标物体&#xff0c;将背景和噪声区分开&#xff08;可以近似的认为除了目标全是噪声&#xff09;。…

掌握TypeScript的类型断言与守卫:提升代码灵活性与安全性

引言 TypeScript的类型系统为JavaScript带来了结构和严谨性&#xff0c;但有时我们需要更多的灵活性。类型断言和类型守卫是TypeScript提供的两个特性&#xff0c;它们允许我们在强类型的环境中进行更细致的类型操作。 基础知识 类型断言&#xff1a;一种明确告诉编译器某个…

GSEA的算法只考虑排序吗

其实这个问题很好回答&#xff0c;只需要运行如下代码&#xff0c;如下的基因列表是顺序是完全相同&#xff0c;并且我们只是做了最基础的变换 library(clusterProfiler) library(org.Hs.eg.db)data(geneList, package"DOSE")ego1 <- gseGO(geneList geneLi…

【iOS】UI学习(二)

UI学习&#xff08;二&#xff09; 进度条和滑动条步进器与分栏控件警告对话框和提示等待器UITextFieldUITextField控件UITextFieldDelegate协议 UIScrollView布局子视图手动布局子视图自动布局子视图 进度条和滑动条 下面通过一个程序来讲解该内容&#xff1a; #import <…