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

39. 组合总和

题目链接:39. 组合总和 - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:带你学透回溯算法-组合总和(对应「leetcode」力扣题目:39.组合总和)| 回溯法精讲!_哔哩哔哩_bilibili

思路:

输入:candidates = [2,3,6,7], target = 7   输出:[[2,2,3],[7]]

定义两个全局变量,二维数组result存放结果集,数组path存放符合条件的结果。

1.递归函数参数

首先是题目中给出的参数,集合candidates, 和目标值target。

此外还定义了int型的sum变量来统计单一结果path里的总和

还需要startIndex来控制for循环的起始位置

2.回溯函数终止条件

终止只有两种情况,sum大于target直接返回;sum等于target的时候,需要收集结果

3.单层搜索的过程

单层for循环依然是从startIndex开始,搜索candidates集合。

剪枝:

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

时间复杂度: O(n * 2^n),空间复杂度: O(target)

40.组合总和II

题目链接:40. 组合总和 II - 力扣(LeetCode)

文章讲解:代码随想录

视频讲解:回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II_哔哩哔哩_bilibili

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

1.递归函数参数

集合candidates, 和目标值target,int型的sum变量来统计单一结果path里的总和,startIndex来控制for循环的起始位置,还需要加一个bool型数组visit,用来记录同一树枝上的元素是否使用过(去重也是visit完成)

2.回溯函数终止条件

终止只有两种情况,sum大于target直接返回;sum等于target的时候,需要收集结果

3.单层搜索的过程

如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1],for循环里就应该做continue的操作。

used[i - 1] == true,说明同一树枝candidates[i - 1]使用过;说明是进入下一层递归,去下一个数,所以是树枝上;

used[i - 1] == false,说明同一树层candidates[i - 1]使用过;因为同一树层,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。

时间复杂度: O(n * 2^n),空间复杂度: O(n)

131.分割回文串

题目链接:​​​​​​​131. 分割回文串 - 力扣(LeetCode)

文章讲解:​​​​​​​代码随想录

视频讲解:带你学透回溯算法-分割回文串(对应力扣题目:131.分割回文串)| 回溯法精讲!_哔哩哔哩_bilibili

思路:

切割问题类似组合问题,例如对于字符串abcdef:

组合问题:选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中再选取第三个.....

切割问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中再切割第三段.....

递归用来纵向遍历,for循环用来横向遍历,切割线(就是图中的红线)切割到字符串的结尾位置,说明找到了一个切割方法

1.递归函数参数

全局变量数组path存放切割后回文的子串,二维数组result存放结果集

还需要startIndex,因为切割过的地方,不能重复切割,和组合问题也是保持一致

2.回溯函数终止条件

从树形结构的图中可以看出:切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止条件;

在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。

3.单层搜索的过程

在for (int i = startIndex; i < s.size(); i++)循环中,我们 定义了起始位置startIndex,那么 [startIndex, i] 就是要截取的子串。

首先判断这个子串是不是回文,如果是回文,就加入在vector<string> path中,path用来记录切割过的回文子串。

切割过的位置,不能重复切割,所以,backtracking(s, i + 1); 传入下一层的起始位置为i + 1

时间复杂度: O(n * 2^n),空间复杂度: O(n^2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值