day23|leetCode 39. 组合总和 , 40.组合总和II , 131.分割回文串

server/2024/11/26 7:58:50/

5.组合总和

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

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

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

对比一下:

找出所有相加之和为 nk 个数的组合,且满足下列条件:

  • 只使用数字1到9

  • 每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

其实我觉得这两题挺像的,最大的区别就是第五题并没有k的限制,所以深度并未被限制

以及元素可以重复选用,所以backtracking(target,candidates,i)传入的应该是i而不是i+1,这样才能保证结果中可以出现重复元素的结果

class Solution {
public:vector<vector<int>>result;vector<int>path;void backtracking(vector<int>&candidates,int target,int sum,int startIndex){//终止条件if(sum>target)//一定加上这个判断,不然就会栈溢出{return;}if(sum==target){result.push_back(path);return;}for(int i = startIndex;i<candidates.size();i++)//注意本题的i是坐标{sum+=candidates[i];path.push_back(candidates[i]);backtracking(candidates,target,sum,i);path.pop_back();sum-=candidates[i];}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();backtracking(candidates,target,0,0);//startIndex在本题传入的是下标,所以从0开始return result;}
};

6.组合总和II

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

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

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

这题更像了

找出所有相加之和为 nk 个数的组合,且满足下列条件:

  • 只使用数字1到9

  • 每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

最大的区别就是去重!

要求是不可在一个组合中使用用一个元素,但是可以用值相等的不同元素!

首先,我们在给backtracking传入数组时,我们不是传入原来的数组,而是将排序过后的数组传入 为什么呢?
示例:输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
如果直接操作原数组,那么在取第一个1的时候,我们会得到一次[1,7],然后在取第二个1的时候,又会得到一次[1,7]就重复了
但是如果我们将数组进行排序,并引入一个bool类型的used数组,这个数组的长度与数组相同,每个位置的false代表这个位置对应的元素已经使用过,如果是true说明这个元素正在使用
排序后的数组:[1,1,2,5,6,7,10]起到将相邻的元素放到一起的作用
然后传入 backtracking(),当循环到第一个1时,将数组used[i]设为true,代表正在历经第一个1能组成的所有结果,遍历完就把used设回false
再循环到第二个1时,通过判断candidates[i]是否与candidates[i-1]相等 && used[i-1]是否为false,如果相等并且used[i-1]=false说明当前这个和前者相同的元素已经遍历完了所有它的可能值,不要再循环了

难点讲解完毕,上代码

class Solution {
public: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++){//注意:sum+candidates[i]<=target是剪枝操作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);used[i]=false;//用过了path.pop_back();//回溯sum-=candidates[i];//}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool>used(candidates.size(),false);//设置used数组来管理使用过的元素result.clear();path.clear();sort(candidates.begin(),candidates.end());//难点,为什么要给数组排序backtracking(candidates,target,0,0,used);return result;}
};

7.分割回文子串

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

回文串

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

示例 1:

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

示例 2:

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

上图是根据给的示例做的分割,不理解的话建议看卡哥的视频讲解,听完就感觉这题很简单了

套用回溯算法模板

void backtracking(参数) {if (终止条件) {存放结果;return;}
​for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}
class Solution {
public:vector<string>path;//存储每一组回文串的集合vector<vector<string>>result;//二维数组,存储最终结果bool isHuiWen(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;}
​void backtracking(const string& s,int startIndex)//startIndex起到切割线的作用{//终止条件if(startIndex >= s.size())//说明已经切割到字符串最后{result.push_back(path);return;}for(int i = startIndex;i<s.size();i++){//startIndex是不变的,但是i是不断增加的//难点:要想到边循环边判断回文if(isHuiWen(s,startIndex,i)==true){//取子串string str = s.substr(startIndex,i-startIndex+1);path.push_back(str);}else{continue;}backtracking(s,i+1);path.pop_back();//回溯弹出}}vector<vector<string>> partition(string s) {result.clear();path.clear();backtracking(s,0);return result;}
};
​
时间复杂度O(n²)


http://www.ppmy.cn/server/145005.html

相关文章

跨平台应用开发框架(1)----Qt(组件篇)

目录 1.Qt 1.Qt 的主要特点 2.Qt的使用场景 3.Qt的版本 2.QtSDK 1.Qt SDK 的组成部分 2.安装 Qt SDK 3.Qt SDK 的优势 3.Qt初识 1.快速上手 widget.cpp mian.cpp widget.h Helloworld.pro 2.对象树 3.坐标系 4.信号和槽 1. 信号和槽的基本概念 2. 信号和槽的…

微服务系统架构图

微服务架构是一种将单一应用程序开发为一组小型服务的架构风格。每个服务都在自己的进程中运行&#xff0c;它们之间采用轻量级的通信机制&#xff08;如 HTTP/REST 或消息队列&#xff09;进行相互协作。以下是关于微服务系统架构的简要介绍&#xff1a;一、核心特点独立部署 …

springboot欢迪迈手机商城设计与开发论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本欢迪迈手机商城就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

DataGrip 连接 Redis、TongRDS

连接 Redis 或 TongRDS 有些旧版本 没有 redis 驱动用不了 1&#xff09;选择驱动 2&#xff09;添加连接信息 3&#xff09;测试连接 4&#xff09;保存连接 5&#xff09;使用案例

如何在 Eclipse 中调试ABAP程序

原文链接&#xff1a;Debugging an ABAP Program ADT 中的调试器是一个重要的诊断工具&#xff0c;可用于分析 ABAP 应用程序。 使用调试器&#xff0c;您可以通过在运行时 Debug 单步执行&#xff08;F5&#xff09;程序来确定程序无法正常工作的原因。这使您可以看到正在执…

wordpress获取文章总数、分类总数、tag总数等

在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值&#xff0c;如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值&#xff0c;本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…

位图与布隆过滤器

欢迎拜访&#xff1a; 羑悻的小杀马特.-CSDN博客 本篇主题&#xff1a;位图与布隆过滤器 制作日期&#xff1a;2024.11.25 隶属专栏&#xff1a;c的不归之路 ------ ->欢迎阅读 欢迎阅读 欢迎阅读 欢迎阅读 <------- 目录…

LabVIEW实现TCP/IP通信

目录 1、TCP通信原理 2、硬件环境部署 3、云端环境部署 4、TCP通信函数 5、程序架构 6、前面板设计 7、程序框图设计 8、测试验证 本专栏以LabVIEW为开发平台&#xff0c;讲解物联网通信组网原理与开发方法&#xff0c;覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合…