代码随想录day23 回溯part2

39.组合总和

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

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

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

示例 1:输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。
示例 2:输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3:输入: candidates = [2], target = 1
输出: []

注意candidates中的数字可以无限次重复被读取
还是和回溯法模板一样,全局变量path和res。需要一个startIndex控制for循环的起始位置。
什么时候需要startIndex:一个集合求组合(例如昨天的两道题)
多个集合求组合就不需要startIndex(电话号码)

每个数字可以重复利用:startIndex每次不用+1。

优化:如果在for循环中剪枝,就需要对数组先进行排序,这样如果sum+candidates[i]>target,那么后面的i肯定也都不符合条件。

class Solution {List<Integer> path;List<List<Integer>> res;int[] candidates;public List<List<Integer>> combinationSum(int[] candidates, int target) {path = new ArrayList<>();res = new ArrayList<>();this.candidates = candidates;Arrays.sort(this.candidates);backtracking(target, 0, 0);return res;}void backtracking(int target, int sum, int startIndex) {// if (target < sum) {//     return;// }if (target == sum) {res.add(new ArrayList<Integer>(path));return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {path.add(candidates[i]);sum += candidates[i];backtracking(target, sum, i);sum -= candidates[i];path.remove(path.size() - 1);}}
}

40.组合总和II

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

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

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

示例 1:输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

数字可以重复,但是不能超过在candicates中出现的次数。比如candidates有两个1,那结果集合不能超过2个1。
所以在上一题的基础上,需要引入一个布尔数组used,标志每个candidates中的数是否被使用了(加入了path)。
Java初始化boolean数组都是false。
回溯函数同样需要index,但是因为candidates中的值不能重复,所以继续回溯还是要i+1。

去重:
同一树枝使用过:同一树枝上的元素都是一个组合里的元素(path),不用去重
同一树层使用过:需要去重,去重前还要先对数组排序。同一树层上相同两个重复元素不能重复选取。所以判断条件就是candidates[i-1]==candidates[i]&&used[i-1]==false。used[i-1]是false说明了i-1元素在上一次回溯使用过,所以不能再选。

class Solution {int[] candidates;List<List<Integer>> res;List<Integer> path;public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates); // 树层去重需要对数组排序this.candidates = candidates;res = new ArrayList<>();path = new ArrayList<>();boolean[] used = new boolean[candidates.length];backtracking(target, 0, 0, used);return res;}void backtracking(int target, int sum, int startIndex, boolean[] used) {if (sum == target) {res.add(new ArrayList<Integer>(path));return;}for (int i = startIndex; i < candidates.length && sum + candidates[i] <= target; i++) {if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) {continue;}sum += candidates[i];path.add(candidates[i]);used[i] = true;backtracking(target, sum, i + 1, used);used[i] = false;path.remove(path.size() - 1);sum -= candidates[i];}}
}

131.分割回文串

给你一个字符串 s,请你将 s 分割成一些 子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

示例 1:输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:输入:s = "a"
输出:[["a"]]

切割问题也类似组合问题,可以使用排序解决。需要一个startIndex标志每次分割开始的位置。
backtracking终止条件:startIndex>=s.length() startIndex已经走到了字符串末尾,说明分割完了
for循环从startIndex的位置开始遍历,每次判断[startIndex,i]子串(闭区间)是否是回文串,如果是,就分割,然后下次回溯从i+1开始。

class Solution {List<String> path;List<List<String>> res;public List<List<String>> partition(String s) {path = new ArrayList<>();res = new ArrayList<>();backtracking(s, 0);return res;}public void backtracking(String s, int startIndex) {if (startIndex >= s.length()) {res.add(new ArrayList<String>(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.remove(path.size() - 1);}}public boolean isPalindrome(String s, int begin, int end) {while (begin < end) {if (s.charAt(begin) != s.charAt(end)) {return false;}begin++;end--;}return true;}
}

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

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

相关文章

回调函数中 qsort 函数的使用

目录 一.冒泡排序 二.指针类型 void* 三. qsort 1.简介 2.研究函数参数 3.怎么用&#xff1f; (1)排数组&#xff0c;升序 (2)排序结构体 四.用冒泡排序思想&#xff0c;模拟实现 qsort (可排序任意类型数据) 1.函数参数设计 2.在 if (cmp( )>0) 怎么传参&#x…

电机控制常见面试问题(十四)

文章目录 一.电机信噪比二.电机零点偏移校正和极对数自适应1.零点偏移量检测​2. 极对数识别三.交流电机电流纹波怎么产生的1.电源相关因素2.电机本体特性3.​PWM逆变器谐波4.负载与环境干扰5.诊断流程建议 四.谈谈对谐波的理解1.谐波定义2.次谐波产生源3.次谐波的检测与分析4.…

axios和fetch的对比

axios 和 fetch 是用于发起 HTTP 请求的两种常见工具&#xff0c;它们的主要区别如下&#xff1a; 1. 浏览器兼容性 axios&#xff1a;基于 XMLHttpRequest&#xff0c;兼容性较好&#xff0c;支持较旧的浏览器&#xff08;如 IE11&#xff09;。fetch&#xff1a;现代浏览器…

Java Timer定时任务源码分析

前言 Java 提供的java.util.Timer类可以用来执行延时任务&#xff0c;任务可以只执行一次&#xff0c;也可以周期性的按照固定的速率或延时来执行。 实现一个延时任务调度器&#xff0c;核心有两点&#xff1a; 如何存储延时任务如何调度执行延时任务 源码分析 TimerTask …

【安全运营】用户与实体行为分析(UEBA)浅析

目录 用户与实体行为分析&#xff08;UEBA&#xff09;简介一、UEBA的核心概念1. 行为基线建立2. 异常检测3. 风险评分4. 上下文关联 二、UEBA的应用场景1. 内部威胁检测2. 外部威胁应对3. 合规性和审计支持 三、UEBA的技术实现1. 大数据技术2. 机器学习算法3. 可视化工具 四、…

系统思考—啤酒游戏经营决策沙盘模拟

再次感谢文华学院的邀请&#xff0c;为经纬集团管理层带来 《啤酒游戏经营决策沙盘》&#xff01; 很多朋友问&#xff1a;“最近是不是啤酒游戏上的少了&#xff1f;” 其实&#xff0c;真正的关键不是游戏本身&#xff0c;而是——如何让大家真正看见复杂系统中的隐性结构。 …

排序算法实现:插入排序与希尔排序

目录 一、引言 二、代码整体结构 三、宏定义与头文件 四、插入排序函数&#xff08;Insertsort&#xff09; 函数作用 代码要点分析 五、希尔排序函数&#xff08;ShellSort&#xff09; 函数作用 代码要点分析 六、打印数组函数&#xff08;PrintSort&#x…

redis的key是如何找到对应存储的数据原理

在 Redis 中,Key 是数据的唯一标识符,而 Value 是与 Key 关联的实际数据。Redis 通过高效的键值对存储机制,能够快速定位和访问数据。以下是 Redis 如何通过 Key 找到对应存储数据的详细解析: 1. Redis 的数据存储结构 Redis 是一个基于内存的键值存储系统,其核心数据结构…

github上传本地文件到远程仓库(空仓库/已有文件的仓库)

今天搞自己本地训练的代码到仓库留个档&#xff0c;结果遇到了好多问题&#xff0c;到腾了半天才搞明白整个过程&#xff0c;留在这里记录一下。 远程空仓库 主要根据官方教程&#xff1a;Adding locally hosted code to GitHub - GitHub Docs #1. cd到你需要上传的文件夹&a…

Redis数据类型详解

Redis数据类型详解 Redis 共有 5 种基本数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zset&#xff08;有序集合&#xff09;。 除了 5 种基本的数据…

【第13章】亿级电商平台订单系统-高性能之异步架构设计

1-1 本章导学 课程导学 学习目标:掌握大型系统架构设计难点之高性能异步架构设计项目落地:订单系统高性能异步架构设计(年交易200亿B2B电商平台)本章主要内容 1. 为何需要异步消息架构 分析同步架构的性能瓶颈异步架构对系统解耦与性能提升的核心价值2. 确定异步消息技术…

2025-03-20 学习记录--C/C++-C 库函数 - toupper()、tolower()、 isspace()

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、C 库函数 - toupper() ⭐️ C 标准库 - <ctype.h> C 标准库的 ctype.h 头文件提供了一些函数&#xff0c;可用于测试和…

LoRaWAN技术解析

LoRaWAN&#xff08;Long Range Wide Area Network&#xff09;是一种基于 LoRa&#xff08;Long Range&#xff09;技术的低功耗广域网络协议&#xff0c;专为物联网&#xff08;IoT&#xff09;设备的无线通信而设计。它是一种开放的、标准化的通信协议&#xff0c;支持大规模…

织梦DedeCMS如何获得在列表和文章页获得顶级或上级栏目名称

获得顶级或二级栏目的名称&#xff0c;都需要修改php文件&#xff0c;修改的文件【/include/common.func.php】将代码插入到这个文件的最下面即可&#xff1b; 一、获得当前文章或栏目的【顶级栏目】名称 1、插入顶级栏目代段 //获取顶级栏目名 function GetTopTypename($id…

虚幻基础:ue自定义类

文章目录 Gameplay Tag&#xff1a;ue标签类创建&#xff1a;其他-数据表格-gameplaytag安装&#xff1a;项目设置&#xff1a;gamePlayTag&#xff1a;gamePlay标签列表使用&#xff1a;变量类型&#xff1a;gamePlayTag primary data asset&#xff1a;ue数据类&#xff1a;通…

易语言模拟真人鼠标轨迹算法

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

Matplotlib 柱形图

Matplotlib 柱形图 引言 在数据可视化领域&#xff0c;柱形图是一种非常常见且强大的图表类型。它能够帮助我们直观地比较不同类别或组之间的数据大小。Matplotlib&#xff0c;作为Python中最受欢迎的数据可视化库之一&#xff0c;提供了丰富的绘图功能&#xff0c;其中包括创…

sparksql的Transformation与 Action操作

Transformation操作 与RDD类似的操作 map、filter、flatMap、mapPartitions、sample、 randomSplit、 limit、 distinct、dropDuplicates、describe&#xff0c;而以上这些都是企业中比较常用的&#xff0c;这里在一个文件中统一论述 val df1 spark.read.json("src/m…

微软Data Formulator:用AI重塑数据可视化的未来

在数据驱动的时代,如何快速将复杂数据转化为直观的图表是每个分析师面临的挑战。微软研究院推出的开源工具 Data Formulator,通过结合AI与交互式界面,重新定义了数据可视化的工作流。本文将深入解析这一工具的核心功能、安装方法及使用技巧,助你轻松驾驭数据之美。 一、Dat…

20分钟上手DeepSeek开发:SpringBoot + Vue2快速构建AI对话系统

20分钟上手DeepSeek开发&#xff1a;SpringBoot Vue2快速构建AI对话系统 前言 在生成式AI技术蓬勃发展的今天&#xff0c;大语言模型已成为企业智能化转型和个人效率提升的核心驱动力。作为国产大模型的优秀代表&#xff0c;DeepSeek凭借其卓越的中文语义理解能力和开发者友…