LeetCode 39. 组合总和 40.组合总和II 131.分割回文串
欢迎关注个人公众号:爱喝可可牛奶
LeetCode 39. 组合总和 40.组合总和II 131.分割回文串
LeetCode 39. 组合总和
分析
回溯可看成对二叉树节点进行组合枚举,分为横向和纵向
每次往sum添加新元素时,必须明确从can哪个位置开始,定义变量pos
返回条件 sum == target 或 sum > target; 横向结束条件 没有新元素可以添加了即pos<can.length;
bt(can, sum, tar, pos){
if(sum == tar) add return;
if(sum > tar) pos++ return;
for(int i = pos; i < can.len;i++){
sum+=can[pos];
bt(can, sum, tar, i);
sum-=can[pos];
}
}
这个回溯考虑sum > tar时, pos++不应该写在第3行,这样导致回溯减掉的元素值与递归添加的不一样。而应该放在第4行for()中,只有当纵向回溯结束时(也就是很多个sum+=can[i]导致return后),横向遍历才会往右移动;回溯第n个can[i] 回溯第n-1个can[i];
剪枝
一次回溯只能抵消一层递归;每次return只是从已经添加进sum的众多can[i]中减掉一个
举个栗子:
sum+= n个can[i],回溯一次还剩n-1个can[i];这时要i++了;但是剩下的sum和这个i++后的新can[i]加起来可能也会超过tar,这步操作可以剪枝,避免进入新can[i]的递归;
for (int i = pos; i < candidates.size() && sum + candidates[i] <= target; i++)
代码
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates); // 先进行排序
backtracking(candidates, target, 0, 0);
return res;
}
public void backtracking(int[] candidates, int target, int sum, int idx) {
// 找到了数字和为 target 的组合
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = idx; i < candidates.length; i++) {
// 如果 sum + candidates[i] > target 就终止遍历
if (sum + candidates[i] > target) break;
path.add(candidates[i]);
backtracking(candidates, target, sum + candidates[i], i);
path.removeLast(); // 回溯,移除路径 path 最后一个元素
}
}
}
LeetCode 40.组合总和II
分析
在原有基础上设限每个数字在每个组合中只能使用 一次 且不包含重复的组合
Arrays升序;纵向遍历时就要i++;Set去重
Set去重超时了!!! 要在添加集合的时候就判断是否重复,取res中最后一个path和当前满足条件的path比较 也不行
纵向递归不需要去重,横向递归时采用去重
剪枝
代码
class Solution {
List<List<Integer>> res = new LinkedList();
LinkedList<Integer> path = new LinkedList();
int sum = 0;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates); // 先进行排序
backtracking(candidates, target, 0);
return res;
}
public void backtracking(int[] candidates, int target, int idx) {
// 找到了数字和为 target 的组合
if (sum == target) {
res.add(new LinkedList<>(path));
return;
}
for (int i = idx; i < candidates.length && sum + candidates[i] <= target; i++) {
// 要对横向遍历时使用过的元素进行跳过 因为一样的元素在深度递归时已经把包含此元素的所有可能结果全部枚举过了
if (i > idx && candidates[i] == candidates[i - 1]) {
continue;
}
path.add(candidates[i]);
sum += candidates[i];
//System.out.println("sum="+sum);
//i++;
backtracking(candidates, target, i+1);
//i--;
//sum -= candidates[i];
sum-=path.getLast();
path.removeLast(); // 回溯,移除路径 path 最后一个元素
}
}
}
LeetCode 131.分割回文串
分析
切割子串,保证每个子串都是 回文串
找到所有的子串组合,判断子串是否是回文串,根据索引切割 startIndex endIndex if(start-end) is ; res.add
代码
class Solution {
List<List<String>> res = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
public List<List<String>> partition(String s) {
backTracking(s, 0);
return res;
}
private void backTracking(String s, int startIndex) {
//如果起始位置大于s的大小,说明找到了一组分割方案
if (startIndex >= s.length()) {
res.add(new ArrayList(path));
return;
}
for (int i = startIndex; i < s.length(); i++) {
//如果是回文子串,则记录
if (isPalindrome(s, startIndex, i)) {
String str = s.substring(startIndex, i + 1);
path.add(str);
} else {
continue;
}
//起始位置后移,保证不重复
backTracking(s, i + 1);
// 一定要有回溯 开始下一种分割
path.removeLast();
}
}
//判断是否是回文串
private boolean isPalindrome(String s, int startIndex, int end) {
for (int i = startIndex, j = end; i < j; i++, j--) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
}
return true;
}
}
总结
- 题目给定的数据集如果使用数组的方式,要判断是否有序,没有说明有序最好视情排序
- 回溯横向移动的时机一定是某个纵向递归结束
- 看清题目要求,将串的所有子串都分割成回文子串
- 横向遍历逻辑 纵向递归startIndex++逻辑 回溯逻辑
LeetCode 39. 组合总和 40.组合总和II 131.分割回文串的更多相关文章
- LeetCode 131. 分割回文串(Palindrome Partitioning)
131. 分割回文串 131. Palindrome Partitioning 题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. LeetC ...
- Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning)
Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning) 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. ...
- Leetcode 131.分割回文串
分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa" ...
- LeetCode 131. 分割回文串(Palindrome Partitioning)
题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa" ...
- Java实现 LeetCode 131 分割回文串
131. 分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa ...
- Java实现 LeetCode 132 分割回文串 II(二)
132. 分割回文串 II 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一 ...
- 【LEETCODE】72、分割回文串 III 第1278题
package y2019.Algorithm.dynamicprogramming.hard; /** * @Auther: xiaof * @Date: 2019/12/11 08:59 * @D ...
- LeetCode 132. 分割回文串 II(Palindrome Partitioning II)
题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一次分割就可将 s ...
- [Swift]LeetCode132. 分割回文串 II | Palindrome Partitioning II
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- 分割回文串 II · Palindrome Partitioning II
[抄题]: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. [思维问题]: 不知道要用预处理字符串降低复杂度 [一句话思路]: 先把预处理获得s中回文串的 ...
随机推荐
- MySQL进阶实战3,mysql索引详解,上篇
一.索引 索引是存储引擎用于快速查找记录的一种数据结构.我觉得数据库中最重要的知识点,就是索引. 存储引擎以不同的方式使用B-Tree索引,性能也各有不同,各有优劣.例如MyISAM使用前缀压缩技术使 ...
- postgresql函数:定期删除模式下指定天数前的表数据及分区物理表
一.现有函数-- 1.现有函数调用select ods.deletePartitionIfExists('fact_ship' || '_' || to_char(CURRENT_DATE - INT ...
- 【课程复习】Java Web、框架及项目简单回顾
JavaEE Day14 Servlet&HTTP&Request&BeanUtils介绍 Servlet类体系结构,两个子抽象类,需要继承HttpServlet而不是Gene ...
- JS中BOM与DOM操作
BOM操作 window对象 是与浏览器窗口做交互的语言 BOM = Browser Object Model 是指浏览器对象模型,它可以使Javascript 有能力和浏览器进行对话 window. ...
- linux基础第二部分
一.Linux命令执行过程 先判断是否是别名,如果是直接执行,不是看是否是内部命令 如果是内部命令,直接执行,不是看hash表 hash表中有源文件直接执行,找不到报错 若hash表中不存在去外部规定 ...
- 前端内容(HTML CSS javaScript)
前端内容 前端基础之HTML 前端基础之HTML HTML标签使用 HTML之form表单 前端基础之CSS 前端基础之CSS CSS字体颜色 背景 盒子模型 CSS浮动 溢出 头像框 CSS定位 i ...
- 从Qt到C#,通过COM组件达成跨语言跨平台链接,或者说从托管到非托管的思路
从Qt到C#,通过COM组件达成跨语言跨平台链接,或者说从非托管到托管 写在前面 c#真的是一种非常蛋疼的语言,和别的语言兼容性差,界面开发效率也不是很高,但是胜在库功能强大,对windows的兼容好 ...
- PyTorch复现AlexNet学习笔记
PyTorch复现AlexNet学习笔记 一篇简单的学习笔记,实现五类花分类 这里只介绍复现的工作,如果想了解更多有关网络的细节,请去看论文<ImageNet Classification wi ...
- week_1
Andrew Ng机器学习笔记---by OrangeStar Week 1 A computer program is said to learn from experience E with re ...
- 使用 Helm 安装 MQTT 服务器-EMQX
EMQX ️ Info: 使用 EMQX 通过 Helm3 在 Kubernetes 上部署 EMQX 4.0 集群 | EMQ emqx/deploy/charts/emqx at main-v4. ...