欢迎关注个人公众号:爱喝可可牛奶

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;
}
}

总结

  1. 题目给定的数据集如果使用数组的方式,要判断是否有序,没有说明有序最好视情排序
  2. 回溯横向移动的时机一定是某个纵向递归结束
  3. 看清题目要求,将串的所有子串都分割成回文子串
  4. 横向遍历逻辑 纵向递归startIndex++逻辑 回溯逻辑

LeetCode 39. 组合总和 40.组合总和II 131.分割回文串的更多相关文章

  1. LeetCode 131. 分割回文串(Palindrome Partitioning)

    131. 分割回文串 131. Palindrome Partitioning 题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. LeetC ...

  2. Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning)

    Leetcode之回溯法专题-131. 分割回文串(Palindrome Partitioning) 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. ...

  3. Leetcode 131.分割回文串

    分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa" ...

  4. LeetCode 131. 分割回文串(Palindrome Partitioning)

    题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa" ...

  5. Java实现 LeetCode 131 分割回文串

    131. 分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa ...

  6. Java实现 LeetCode 132 分割回文串 II(二)

    132. 分割回文串 II 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一 ...

  7. 【LEETCODE】72、分割回文串 III 第1278题

    package y2019.Algorithm.dynamicprogramming.hard; /** * @Auther: xiaof * @Date: 2019/12/11 08:59 * @D ...

  8. LeetCode 132. 分割回文串 II(Palindrome Partitioning II)

    题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一次分割就可将 s ...

  9. [Swift]LeetCode132. 分割回文串 II | Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  10. 分割回文串 II · Palindrome Partitioning II

    [抄题]: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. [思维问题]: 不知道要用预处理字符串降低复杂度 [一句话思路]: 先把预处理获得s中回文串的 ...

随机推荐

  1. day04-功能实现03

    家居网购项目实现03 8.功能07-后台管理 显示家居 8.1需求分析/图解 给后台管理提供独立登录页面,管理员登录地址不对外公开 管理员登录成功后,显示管理菜单页面 管理员点击家居管理,显示所有家居 ...

  2. Django 连接各数据库配置汇总(sqlite3,MySql,Oracle)

    在django中,默认配置的数据库是 sqlite3 # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#database ...

  3. Django(1) - 初识Django框架

    1.前言 该专栏学习笔记环境参数如下: Windows 10 Xampp/Navicat for MySQL Python 3.8+ Django 3.0.* Vue 2.6+ 开发工具: PyCha ...

  4. Redis 如何批量设置过期时间?PIPLINE的使用

    合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ 抛出问题 Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 给出方案 我们引入redi ...

  5. 关于asp.net mvc的控制器的依赖注入思考及对StructureMap依赖注入框架的简单实践笔记

    写在前面: 依赖注入这个玩意很多人其实都接触过,但可能没有细究其中的原理. 比如Controller的构造函数中,只要你传入一些接口,应用自动就给你处理了创建的过程,无需你手动去new 一个实例并穿进 ...

  6. [图像处理] YUV图像处理入门2

    1 分离YUV420中YUV分量 本程序中的函数主要是将YUV420P视频数据流的第一帧图像中的Y.U.V三个分量分离开并保存成三个文件.函数的代码如下所示: /** * @file 1 yuv_sp ...

  7. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记4

    1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本.不过不用 ...

  8. Jasypt与Apollo一起使用造成Apollo热更新失效问题分析

    背景 近日业务同学反映在Apollo界面更改配置后, 服务中对应变量的值却没有改变 相关配置key定义如下: @ApolloJsonValue("${apollo.config.map:{} ...

  9. Java基础篇——JVM初步

    1.JVM的位置 2.JVM体系结构 3.类加载器 虚拟机加载器(java) 启动类(根)加载器(C++) 扩展类加载器(java)↑ 应用程序加载器(java)↑ 4.双亲委派机制 类加载器收到类加 ...

  10. 使用Logstash工具导入sqlserver数据到elasticSearch及elk分布式日志中心

    首先记下这个笔记,Logstash工具导入sqlserver数据到elasticSearch. 因为logstash使用java写的,我本地开发是win11,所以javade jdk必须要安装.具体安 ...