代码随想录day23 | leetcode 39.组合总和 40.组合总和II 131.分割回文串

39.组合总和

Java

class Solution {     List<List<Integer>> result = 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 result;}public void backtracking(int[] candidates,int target,int sum,int startIndex){if (sum>target){return;}if (sum == target){result.add(new LinkedList<>(path));return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {path.add(candidates[i]);sum += candidates[i];backtracking(candidates,target,sum,i);sum -= candidates[i];path.removeLast();}}
}
回溯方法:backtracking
public void backtracking(int[] candidates, int target, int sum, int startIndex) {if (sum > target) { // 剪枝:如果当前和已经超过目标,直接返回return;}if (sum == target) { // 找到满足条件的组合result.add(new LinkedList<>(path)); // 保存当前路径到结果return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {path.add(candidates[i]); // 做选择:将当前数字加入路径sum += candidates[i]; // 更新路径总和backtracking(candidates, target, sum, i); // 递归,允许重复选择当前数字sum -= candidates[i]; // 撤销选择:恢复之前的状态path.removeLast(); // 从路径中移除最后一个数字,回溯}
}
逻辑解释
  1. 递归终止条件
    • sum > target:当前路径总和超过目标值,停止递归。
    • sum == target:找到一组符合条件的组合,将 path 复制加入结果。
  2. 循环递归
    • 循环起点:从 startIndex 开始,保证每次递归处理当前数字及其后续数字。
    • 条件:sum + candidates[i] <= target- 剪枝条件,提前终止无意义的递归。
    • 允许重复选择:- 递归调用时仍从 i 开始 (backtracking(candidates, target, sum, i)),因此当前数字可以重复加入组合。
  3. 回溯过程
    • path.add(candidates[i])path.removeLast():分别表示“选择当前数字”和“撤销选择”。
    • sum += candidates[i]sum -= candidates[i]:动态更新当前路径的总和。

40.组合总和II

树层去重一个数完整搜完一边,另一个重复的数不用搜第二遍

Java

class Solution {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);boolean[] used = new boolean[candidates.length];Arrays.fill(used,false);backtracking(candidates,target,0,0,used);return result;}public void backtracking(int[] candidates, int target,int sum,int stateIndex,boolean[] used){if (sum>target){return;}if (sum == target){result.add(new ArrayList<>(path));}for (int i = stateIndex; i < candidates.length; i++) {if (i>0&&candidates[i-1]==candidates[i]&&used[i-1]==false){//重要,按层去重continue;}path.add(candidates[i]);sum += candidates[i];used[i] = true;backtracking(candidates,target,sum,i+1,used);path.removeLast();sum -= candidates[i];used[i] = false;}}
}

关键点

  1. 数组排序
	Arrays.sort(candidates);

对数组 candidates 进行排序是为了方便去重和剪枝。排序后,相同的元素会相邻,可以通过简单的逻辑避免重复。

  1. 去重逻辑
	if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) {continue;}

这一部分用于按“层”去重。如果当前元素与前一个元素相同,且前一个元素在当前层没有被使用(used[i - 1] == false),就跳过这个元素,避免重复组合。

  1. 递归与回溯
    • 递归条件:递归深入到下一层(选择下一个数字)。
    • 回溯操作:撤销上一步的选择(移除当前路径中的数字,恢复 sumused 的状态)。

代码逻辑

全局变量
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
  • result:存储最终的所有满足条件的组合。
  • path:存储当前递归路径上的数字组合。

主函数
public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates); // 排序,方便去重和剪枝boolean[] used = new boolean[candidates.length]; // 记录每个数字是否使用backtracking(candidates, target, 0, 0, used); // 初始状态return result;
}
  • 对数组排序后,初始化 used 数组为 false
  • 调用回溯函数 backtracking 开始寻找组合。

回溯函数
public void backtracking(int[] candidates, int target, int sum, int stateIndex, boolean[] used) {if (sum > target) {return; // 剪枝:当前组合和大于目标值}if (sum == target) {result.add(new ArrayList<>(path)); // 找到符合条件的组合,加入结果集return;}for (int i = stateIndex; i < candidates.length; i++) {if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) {continue; // 去重:跳过相同的元素}path.add(candidates[i]); // 添加当前数字到路径sum += candidates[i]; // 更新路径和used[i] = true; // 标记当前数字为已使用backtracking(candidates, target, sum, i + 1, used); // 递归到下一层path.removeLast(); // 回溯,撤销选择sum -= candidates[i]; // 恢复路径和used[i] = false; // 恢复使用状态}
}

重点逻辑

  1. 递归结束条件
    • sum > target 时,直接返回,表示当前路径无效。
    • sum == target 时,说明找到一个符合条件的组合,将其加入 result
  2. 去重
	if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) {continue;
}

按“层”去重。只有当前层的数字和前一个数字相同时,才需要检查是否跳过。
3. 递归与回溯
- 递归:将当前数字加入路径后,继续递归处理下一层。
- 回溯:撤销选择,包括移除路径中的数字,恢复 sumused 的状态。

131.分割回文串

Java

class Solution {List<List<String>> result = new ArrayList<>();LinkedList<String> path = new LinkedList<>();public List<List<String>> partition(String s) {backtracking(s,0);return result;}public void backtracking(String s,int startIndex){if (startIndex >= s.length()){result.add(new ArrayList<>(path));return;}for (int i = startIndex; i < s.length(); i++) {if (isPalindrome(s,startIndex,i)){String a = s.substring(startIndex,i+1);path.add(a);}else {continue;}backtracking(s,i+1);path.removeLast();}}boolean isPalindrome(String s,int start,int end){for (int i = start,j = end; i <j ; i++,j--) {if (s.charAt(i)!=s.charAt(j)){return false;}}return true;}
}
全局变量
List<List<String>> result = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
  • result:存储所有满足条件的分割方案。
  • path:当前递归路径,表示当前的分割方案。

主函数
public List<List<String>> partition(String s) {backtracking(s, 0); // 从索引 0 开始划分字符串return result;
}
  • 调用回溯函数 backtracking 从字符串的第一个字符开始分割。
  • 返回所有满足条件的方案。

回溯函数
public void backtracking(String s, int startIndex) {if (startIndex >= s.length()) {result.add(new ArrayList<>(path)); // 如果遍历到字符串末尾,记录当前路径return;}for (int i = startIndex; i < s.length(); i++) {if (isPalindrome(s, startIndex, i)) { // 判断从 startIndex 到 i 的子串是否是回文String a = s.substring(startIndex, i + 1); // 取出当前回文子串path.add(a); // 加入路径} else {continue; // 如果不是回文,跳过本次循环}backtracking(s, i + 1); // 递归处理剩下的部分path.removeLast(); // 回溯,移除最后一个子串}
}
  • 终止条件:- 当 startIndex 超过或等于字符串长度时,说明已经分割完毕,记录当前路径。
  • 递归逻辑:- 从 startIndex 开始,尝试分割到每个可能的位置 i
    • 如果 s[startIndex...i] 是回文,则加入路径,并递归处理 s[i+1...end]
    • 递归返回后,回溯移除当前子串。

判断是否为回文
boolean isPalindrome(String s, int start, int end) {for (int i = start, j = end; i < j; i++, j--) {if (s.charAt(i) != s.charAt(j)) {return false; // 如果两端字符不相等,不是回文}}return true; // 如果所有字符都相等,是回文
}
  • 双指针法,检查从 startend 的子串是否为回文。
  • 左右两端字符逐步比较,如果有任意一对不相等,则不是回文。

算法流程

  1. 从字符串 s 的第一个字符开始,尝试划分每个可能的回文子串。
  2. 如果找到一个回文子串,加入当前路径,并继续递归处理剩余部分。
  3. 当划分到字符串末尾时,将当前路径记录为一种有效方案。
  4. 回溯时移除最后一个子串,尝试其他划分方式。

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

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

相关文章

【day11】面向对象编程进阶(继承)

概述 本文深入探讨面向对象编程的核心概念&#xff0c;包括继承、方法重写、this和super关键字的使用&#xff0c;以及抽象类和方法的定义与实现。通过本文的学习&#xff0c;你将能够&#xff1a; 理解继承的优势。掌握继承的使用方法。了解继承后成员变量和成员方法的访问特…

高效准确的PDF解析工具,赋能企业非结构化数据治理

目录 准确性高&#xff1a;还原复杂版面元素 使用便捷&#xff1a;灵活适配场景 贴心服务&#xff1a;快速响应机制 在数据为王的时代浪潮中&#xff0c;企业数据治理已成为组织优化运营、提高竞争力的关键。随着数字化进程的加速&#xff0c;企业所积累的数据量呈爆炸式增长…

Unity全局雾效

1、全局雾效是什么 全局雾效&#xff08;Global Fog&#xff09;是一种视觉效果&#xff0c;用于在3D场景中模拟大气中的雾气对远处物体的遮挡 它通过在场景中加入雾的效果&#xff0c;使得距离摄像机较远的物体看起来逐渐被雾气覆盖&#xff0c;从而创造出一种朦胧、模糊的视…

解决Apache/2.4.39 (Win64) PHP/7.2.18 Server at localhost Port 80问题

配置一下apache里面的配置文件&#xff1a;httpd.conf 和 httpd.vhosts.conf httpd.conf httpd-vhosts.conf 重启服务 展示&#xff1a; 浏览器中中文乱码问题&#xff1a;

【Spring事务】深入浅出Spring事务从原理到源码

什么是事务 保证业务操作完整性的一种数据库机制 &#xff08;driver 驱动&#xff09;事务特定 ACID A 原子性 &#xff08;多次操作 要不一起成功 要不一起失败 &#xff08;部分失败 savepoint&#xff09;&#xff09; C 一致性 &#xff08;事务开始时数据状态&#xff0c…

MFC/C++学习系列之简单记录13

MFC/C学习系列之简单记录13 前言memsetList Control代码注意 总结 前言 今天记录一下memset和List control 的使用吧&#xff01; memset memset通常在初始化变量或清空内存区域的时候使用&#xff0c;可以对变量设定特定的值。 使用&#xff1a; 头文件&#xff1a; C&#…

C# cad启动自动加载启动插件、类库编译 多个dll合并为一个

可以通过引用costura.fody的包&#xff0c;编译后直接变为一个dll 自动加载写入注册表、激活码功能: 【CAD二次开发教程-实例18-启动加载与自动运行-哔哩哔哩】 https://b23.tv/lKnki3f https://gitee.com/zhuhao1912/cad-atuo-register-and-active

Android Studio AI助手---Gemini

从金丝雀频道下载最新版 Android Studio&#xff0c;以利用所有这些新功能&#xff0c;并继续阅读以了解新增内容。 Gemini 现在可以编写、重构和记录 Android 代码 Gemini 不仅仅是提供指导。它可以编辑您的代码&#xff0c;帮助您快速从原型转向实现&#xff0c;实现常见的…

固定电话采用的是模拟信号还是数字信号?如果通话两端采用不同的信号会发生什么?

固定电话信号大揭秘&#xff1a;模拟与数字信号的纠缠 模拟信号 VS 数字信号&#xff1a;谁是电话界的“老江湖”&#xff1f; 固定电话采用的是模拟信号还是数字信号&#xff1f; 这其实取决于接入方式&#xff1a; 铜线接入&#xff1a;传统方式&#xff0c;使用模拟电信号…

<项目代码>YOLO Visdrone航拍目标识别<目标检测>

项目代码下载链接 &#xff1c;项目代码&#xff1e;YOLO Visdrone航拍目标识别&#xff1c;目标检测&#xff1e;https://download.csdn.net/download/qq_53332949/90163918YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一…

druid与pgsql结合踩坑记

最近项目里面突然出现一个怪问题&#xff0c;数据库是pgsql&#xff0c;jdbc连接池是alibaba开源的druid&#xff0c;idea里面直接启动没问题&#xff0c;打完包放在centos上和windows上cmd窗口都能直接用java -jar命令启动&#xff0c;但是放到国产信创系统上就是报错&#xf…

LabVIEW电机控制中的主动消抖

在LabVIEW电机控制系统中&#xff0c;抖动现象&#xff08;如控制信号波动或机械振动&#xff09;会影响系统的稳定性和精度。通过使用主动消抖算法&#xff0c;可以有效降低抖动&#xff0c;提高控制性能。本文将介绍几种主流的主动消抖算法&#xff0c;并结合具体应用案例进行…

Vue CLI 脚手架创建项目流程详解 (2)

更新 CLI 脚手架 确保你安装的是最新版本的 Vue CLI&#xff0c;以支持最新的特性及改进。你可以通过以下命令全局安装或更新 Vue CLI&#xff1a; npm install -g vue/cli创建 Vue 3.x 项目 启动创建向导 使用 vue create 命令来开始创建一个新的 Vue 项目&#xff1a; vue …

macos 隐藏、加密磁盘、文件

磁盘加密 打开磁盘工具 点击添加 设置加密参数 设置密码 查看文件 不用的时候右键卸载即可使用的时候装载磁盘&#xff0c;并输入密码即可 修改密码 解密 加密&#xff0c;输入密码即可 禁止开机自动挂载此加密磁盘 如果不禁止自动挂载磁盘&#xff0c;开机后会弹出输入…

Chapter 19 Layout and Packaging

Chapter 19 Layout and Packaging 这一章我们介绍版图和封装, 关注模拟和数字电路的要求. 首先讲模拟电路中layout设计考虑, 然后解决衬底coupling问题, 最后描述封装问题, 分析IC的外部电容和电感问题. 19.1 General Layout Considerations 19.1.1 Design Rules Minimum W…

c++ ------语句

一、简单语句 简单语句是C中最基本的语句单元&#xff0c;通常以分号&#xff08;;&#xff09;结尾&#xff0c;用于执行一个单一的操作。常见的简单语句类型有&#xff1a; 表达式语句&#xff1a;由一个表达式后面加上分号构成&#xff0c;用于计算表达式的值或者执行具有…

OpenResty、Lua介绍认识

文章目录 官网网址openrestry介绍OpenResty 的关键特性包括&#xff1a;应用场景&#xff1a;Lua 在 OpenResty 中的应用 安装openrestry简单实验下 官网网址 开源版在线文档和支持 商业版支持 什么是Lua 学习Lua语法 每篇一问&#xff1a;什么是编译型语言&#xff0c;什么是…

Flutter组件————Container

Container Container 是 Flutter 中最常用的布局组件之一 参数 参数名称类型描述alignmentAlignmentGeometry定义子组件在其内部的对齐方式&#xff0c;默认为 null&#xff0c;即不改变子组件的位置。paddingEdgeInsetsGeometry内边距&#xff0c;用于在子组件周围添加空间…

36. Three.js案例-创建带光照和阴影的球体与平面

36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器&#xff0c;用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…

vue2 - Day03 - (生命周期、组件、组件通信)

文章目录 一、生命周期1. 创建阶段2. 挂载阶段3. 更新阶段4. 销毁阶段5. 错误捕获总结 二、组件2.1 注册1. 全局注册 - 公共的组件。2. 局部注册总结 2.2 三大重要的组成部分1. 模板 (Template)主要功能&#xff1a;说明&#xff1a; 2. 脚本 (Script)主要功能&#xff1a;说明…