Leetcoder Day23| 回溯part03:组合+分割

语言:Java/Go

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 。仅有这两种组合。

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40

本题的一大特点是没有组合数量的要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。这里的剪枝操作就是,如果当前的sum已经大于target。

class Solution {List<List<Integer>> res= new ArrayList<>();LinkedList<Integer> path =new LinkedList<>();public void backTracking(int[] candidates, int target, int sum, int startIdx){if(sum == target){res.add(new ArrayList<>(path));return;}if(sum > target) return;for(int i = startIdx; i < candidates.length; i++){sum += candidates[i];path.add(candidates[i]);if (sum <= target) {backTracking(candidates, target, sum, i);  //注意这里传递的是 i,而不是i+1,为了可以重复取值}sum -= candidates[i];path.removeLast();}}public List<List<Integer>> combinationSum(int[] candidates, int target) {backTracking(candidates, target, 0, 0);return res;}
}
  • 组合没有数量要求
  • 元素可无限重复选取

组合总结

1. 什么时候需要startIdx:如果是一个集合来求组合,就需要,如果是多个集合取组合,就不需要。

2. 什么时候在调用递归backTracking ()的时候+1:如果不可以重复,则需要+1,否则不用+1

40.组合总和II

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

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

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

  • 示例 1:
  • 输入: candidates = [10,1,2,7,6,1,5], target = 8,
  • 所求解集为:
[[1, 7],[1, 2, 5],[2, 6],[1, 1, 6]
]
  • 示例 2:
  • 输入: candidates = [2,5,2,1,2], target = 5,
  • 所求解集为:
[[1,2,2],[5]
]

本题和上一题的区别在于:

  1. 本题candidates中的每个数字在每个组合中只能使用一次。
  2. 本题数组candidates的元素是有重复的,而上一题是无重复元素的数组candidates

关于使用一次这个问题的理解:组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。示例中给出的组合,在同一个组合中可以有重复,但是不能有重复的组合。

同一树枝上的都是一个组合里的元素,不用去重。同一树层上的是不同的组合,所以不可以重复。具体来讲,假如数组为[1,1,2,7],那么如果第一个1取完以后,继续从剩下的两个元素中取值会出现[1,1],[1,2],[1,7]这个操作是可以的,因为前两个1只是数值相同但并不是同一个元素,但是如果第一次取的是第二个1,那么其实后面的取值过程会和取第一个1的时候重复,这就造成了树层的重复。所以去重的方法就是,将当前的candidates数组排序以后,如果candidates[i]=candidates[i-1] 就跳过当前循环,继续寻找下一个数。

其实可以不借助新的数组,用startIdx进行去重也可以。

import java.util.Arrays;
class Solution {List<List<Integer>> res=new ArrayList<>();LinkedList<Integer> path =new LinkedList<>();public void backTracking(int[] candidates, int target, int sum, int startIdx){if(sum>target) return;if(sum == target){res.add(new ArrayList<>(path));}for(int i=startIdx;i<candidates.length;i++){// 要对同一树层使用过的元素进行跳过if(i>startIdx && candidates[i]==candidates[i-1]){continue;}sum+=candidates[i];path.add(candidates[i]);if(sum<=target){backTracking(candidates, target, sum,i+1);}sum-=candidates[i];path.removeLast();}}public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);backTracking(candidates, target, 0,0);return res;}
}

131.分割回文串

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

回文串 是正着读和反着读都一样的字符串。

示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]

这道题需要解决两个问题:(1)如何切割(2)怎么判断是否为回文串

切割问题其实类似于组合问题,也可以抽象为一个树结构

这里切割过的地方,不能重复切割,和组合问题也是保持一致的,所以也需要startIdx。

从图中可以看到,切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止条件。每次切割是从startIdx开始的,所以startIdx即为切割线。当startIdx>=s.length()时,切割终止。

每切割一次,就要判断剩下的子串是否为回文串,如果是回文串,就将其加入path中。如果不是,就跳过。

可以用双指针法判断是否为回文串,设置start和end指针,如果前后指针所指向的元素相等,直到start==end,那么就是回文串。

class Solution {List<List<String>> res=new ArrayList<>();LinkedList<String> path = new LinkedList();public 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;}public void backTracking(String s, int startIdx){if(startIdx>=s.length()){res.add(new ArrayList<>(path));}for(int i=startIdx;i<s.length();i++){if(isPalindrome(s, startIdx, i)){String str=s.substring(startIdx, i+1);path.add(str);}else{continue;}backTracking(s, i+1); //确保不重复path.removeLast();}}public List<List<String>> partition(String s) {backTracking(s,0);return res;}
} 

本题难点和思路如下:

  • 切割问题可以抽象为组合问题
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 如何判断回文

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

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

相关文章

环形光源让图像质量瞬间提升,一探究竟吧!

光源对机器视觉检测系统的性能起着重要作用,精确的光学结构设计可以提高捕获图像的质量,准确地分离目标和背景信息,不充足的光线会使捕捉到的图像无法满足需求&#xff0c;针对不同的检测对象,不同的形状光源应运而生。我们来看看最常用的LED光源之一—环形光源。 环形光源&…

vue3 使用pina

一、Vue 3 项目中集成Pina 状态管理库 要在 Vue 3 项目中使用 Pina&#xff08;Vue 3 状态管理库&#xff09;&#xff0c;您可以按照以下步骤操作&#xff1a; 1. 安装 Pina 库相应的插件&#xff1a; yarn add pinia # 或者使用 npm npm install pinia 2. 在您的 Vue 3 项…

电脑休眠之后唤不醒

现象&#xff1a;午休时间电脑休眠了&#xff0c;醒来之后发现在密码输入界面&#xff0c;但鼠标键盘没反应。按重启键或电源机重新开机&#xff0c;结果开不了机。 原因&#xff1a;1、内存条脏了&#xff0c;导致内存条读取失败 2、休眠的时候硬盘休眠了&#xff0c;导致按…

AngularJS安装版本问题

一、安装 Angular CLI 脚手架安装命令&#xff1a; npm install -g angular/cli 在安装前请确保自己安装NodeJS环境版本为V18及以上&#xff0c;否则会因node版本问题导致项目无法正常运行。 脚手架安装后&#xff0c;已提示了当前node版本必须为18.13.0或大于20.9.0版本&…

git之分支管理

一.理解分支 我们看下面这张图片&#xff1a; 在版本回退⾥&#xff0c;你已经知道&#xff0c;每次提交&#xff0c;Git都把它们串成⼀条时间线&#xff0c;这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前&#xff0c;只有⼀条时间线&#xff0c;在Git⾥&#xff0c;这个分⽀…

2024年 前端JavaScript入门到精通 第四天 笔记

4.1 函数的基本使用以及封装练习 ★ 函数命名规范 4.2 函数的参数以及默认参数 函数的灵魂&#xff01;&#xff01;&#xff01; 4.3 函数封装数组求和案例 4.4 函数返回值return 4.5 函数返回值细节以及上午总结 4.6 函数返回值案例-求最大值和最 4.7 函数复习以及断点进入函…

如何在Linux搭建MinIO服务并实现无公网ip远程访问内网管理界面

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

挑战杯 基于机器视觉的12306验证码识别

文章目录 0 简介1 数据收集2 识别过程3 网络构建4 数据读取5 模型训练6 加入Dropout层7 数据增强8 迁移学习9 结果9 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的12306验证码识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向…

Inno setup 打包jar包+前端dist+mysql+navicat等应用文件操作

目录 一、 使用exe4j将后端jar包打包成exe应用文件 1.创建一个新的工程 2.选择一个你想要存放的路径 3.进入配置界面 4.选择jar转换exe模式 5.自定义名字和选择输出路径 6.配置初始化 7.配置java环境 8.测试运行结果 二、Inno 打包应用文件exe 1.新建一个工程文件 2…

【hashmap】【将排序之后的字符串作为哈希表的键】【获取 HashMap 中所有值的集合】Leetcode 49 字母异位词分组

【hashmap】【将排序之后的字符串作为哈希表的键】【获取 HashMap 中所有值的集合】Leetcode 49 字母异位词分组 解法1 将排序之后的字符串作为哈希表的键解法2 在解法一的基础上加入了getOrDefault ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f3…

从零开始手写mmo游戏从框架到爆炸(二十二)— 战斗系统三

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 目录 地图设定 战斗引擎 服务端的BattleHandler 客户端的相关handler 战斗场景展示 执行效果 文接上一章。我们把战斗系统demo应用到实际的项目中来。在第十九章&#xf…

AI对话系统app开源

支持对接gpt&#xff0c;阿里云&#xff0c;腾讯云 具体看截图 后端环境&#xff1a;PHP7.4MySQL5.6 软件&#xff1a;uniapp 废话不多说直接上抗揍云链接&#xff1a; https://mny.lanzout.com/iKFRY1o1zusf 部署教程请看源码内的【使用教程】文档 欢迎各位转载该帖/源码

智慧公厕是什么?智慧公厕意义何在

随着城市化进程的加速&#xff0c;公厕成为城市管理中不容忽视的一环。智慧公厕传统的公厕管理方式已经无法满足当今社会的需求&#xff0c;因此智慧公厕的出现成为解决问题的利器。什么是智慧公厕&#xff1f;智慧公厕是实现公共厕所信息化、数字化、智慧化全方位管理与服务的…

啤酒:精酿啤酒与烧烤的热烈碰撞

在夏日的傍晚&#xff0c;烧烤与啤酒总是绝配。当Fendi Club啤酒遇上烧烤&#xff0c;它们将为我们带来一场热烈的美味碰撞。 Fendi Club啤酒&#xff0c;以其醇厚的口感和淡淡的麦芽香气而著称。这款啤酒在酿造过程中采用了特别的工艺&#xff0c;使得酒体呈现出诱人的金黄色&…

F2图例封装 - Bar

基于vue3 和 F2 3.5.0 <template><div :style"{minHeight: ${height}px,width: 100% }" ref"container"><canvas v-show"showChart" :id"chartId" class"chart-canval"></canvas><empty-box v-…

零感佩戴的开放式耳机,音质悦耳更耐听,西圣Air体验

每天都用蓝牙耳机的朋友应该不少&#xff0c;我平时也经常戴&#xff0c;不过最近我用的不是常规的入耳式耳机&#xff0c;因为它佩戴不舒适&#xff0c;戴久了耳朵特别难受。所以现在我换上了开放式耳机&#xff0c;这种耳机叫做OWS&#xff0c;我的这款是西圣Air&#xff0c;…

查看mysql数据库的版本

要查看MySQL数据库的版本&#xff0c;可以使用以下几种方法&#xff1a; 命令行&#xff08;已连接到MySQL服务器&#xff09;&#xff1a; 登录到MySQL服务器后&#xff0c;在MySQL提示符下执行&#xff1a; mysql> SELECT VERSION(); 或者&#xff0c;也可以执行 STATUS; …

Java异常梳理总结

目录 什么是异常 , 异常的分类 ? 异常的基本概念 什么是Throwable ? Throwable 类常用方法有哪些&#xff1f; Exception 和 Error 有什么区别&#xff1f; 运行时异常与一般异常有什么区别&#xff1f; 常见的RuntimeException 有哪些 ? NoClassDefFoundError 和 C…

面试总结之JVM入门

文章目录 &#x1f412;个人主页&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;你为什么要学习JVM&#xff1f;&#x1f380;JVM的作用 &#x1f380;JVM的构成&#xff08;5大类&#xff09;&#x1f3e8;1.类加载系统&#x1f415;类什么时候会被加…

《业务建模驱动的企业架构转型白皮书》

当前&#xff0c;我国金融等国民经济重点行业和企业的数字化转型&#xff0c;仍存在战略落地难、业务技术协同难以及投入产出匹配难等问题&#xff0c;亟需通过实施企业架构&#xff0c;从顶层设计出发&#xff0c;制定符合自身需要的转型战略&#xff1b;从全局视角出发&#…