代码随想录算法训练营第day26|39. 组合总和、 40.组合总和II、 131.分割回文串

39. 组合总和

力扣题目链接(opens new window)

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

  • 输入:candidates = [2,3,6,7], target = 7,
  • 所求解集为: [ [7], [2,2,3] ]

示例 2:

  • 输入:candidates = [2,3,5], target = 8,
  • 所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]

思路:

本题搜索的过程抽象成树形结构如下:

39.组合总和

 注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!

本题还需要startIndex来控制for循环的起始位置,对于组合问题,什么时候需要startIndex呢?如果是一个集合来求组合的话,就需要startIndex;如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum == target) {result.push_back(path);return;}//横向遍历树结构for (int i = startIndex; i < candidates.size(); i++) {sum += candidates[i];path.push_back(candidates[i]);// 纵向遍历树结构backtracking(candidates, target, sum, i); // 不用i+1了,表示可以重复读取当前的数sum -= candidates[i];//回溯path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();backtracking(candidates, target, 0, 0);return result;}
};

40.组合总和II

力扣题目链接(opens new window)

给定一个数组 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]
]

思路:

这道题目和39.组合总和 (opens new window)如下区别:

  1. 本题candidates 中的每个数字在每个组合中只能使用一次。
  2. 本题数组candidates的元素是有重复的,而39.组合总和 (opens new window)是无重复元素的数组candidates

最后本题和39.组合总和 (opens new window)要求一样,解集不能包含重复的组合。

本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合

一些同学可能想了:我把所有组合求出来,再用set或者map去重,这么做很容易超时!

所以要在搜索的过程中就去掉重复组合。

我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重

为了理解去重我们来举一个例子,candidates = [1, 1, 2], target = 3,(方便起见candidates已经排序了)

强调一下,树层去重的话,需要对数组排序!

选择过程树形结构如图所示:

40.组合总和II

与39.组合总和 (opens new window)套路相同,此题还需要加一个bool型数组used,用来记录同一树枝上的元素是否使用过。

这个集合去重的重任就是used来完成的。

前面我们提到:要去重的是“同一树层上的使用过”,如何判断同一树层上元素(相同的元素)是否使用过了呢。

如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1]

此时for循环里就应该做continue的操作。

在candidates[i] == candidates[i - 1]相同的情况下:

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

可能有的录友想,为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。

而 used[i - 1] == true,说明是进入下一层递归,去下一个数,所以是树枝上,如图所示:

 

class Solution {
public:vector<int>path;vector<vector<int>>result;// int sum=0;void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool> used){//终止条件if(sum==target) {result.push_back(path);return;}if(sum>target)return;//横向遍历树状结构// &&sum+candidates[i]<target是为了剪枝,剪去不必要的遍历for(int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++){//同层去重if(i>0&&candidates[i]==candidates[i-1]&&used[i-1]==false){continue;}sum+=candidates[i];path.push_back(candidates[i]);used[i]=true;backtracking(candidates, target, sum, i+1, used);//纵向遍历,递归,i+1开始,因为不可重复选择同一元素//回溯sum-=candidates[i];path.pop_back();used[i]=false;}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool>used(candidates.size(), false);path.clear();result.clear();sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return result;}
};

9.分割回⽂串 

131. 分割回文串 - 力扣(LeetCode)

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

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

思路:本题这涉及到两个关键问题:

1. 切割问题,有不同的切割⽅式

2. 判断回⽂

我们来分析⼀下切割,其实切割问题类似组合问题。 例如对于字符串abcdef:

组合问题:选取⼀个a之后,在bcdef中再去选取第⼆个,选取b之后在cdef中再选取第三个.....。

切割问题:切割⼀个a之后,在bcdef中再去切割第⼆段,切割b之后在cdef中再切割第三段.....

所以切割问题,也可以抽象为⼀棵树形结构

全局变量数组path存放切割后回⽂的⼦串,⼆维数组result存放结果集。 (这两个参数可以放到函数参数⾥) 本题递归函数参数还需要startIndex,因为切割过的地⽅,不能重复切割,和组合问题也是保持⼀致的。

终止条件:切割线切到了字符串最后⾯,说明找到了⼀种切割⽅法,此时就是本层递归的终⽌条 件

class Solution {
public:vector<string>path;vector<vector<string>>result;void backtracking(string& s, int startIndex){if(startIndex>=s.size()){//递归结束条件result.push_back(path);}//横向遍历树状结构for(int i=startIndex;i<s.size();i++){if(isPalindrome(s, startIndex, i)){//判断是否为回文字符串//截取回文串string str =s.substr(startIndex, i-startIndex+1);path.push_back(str);}else continue;//纵向遍历树结构backtracking(s,i+1);path.pop_back();//回溯}}bool isPalindrome(string& s, int startIndex, int endIndex){for(int i=startIndex,j=endIndex;i<j;i++,j--){if(s[i]!=s[j]) return false;}return true;}vector<vector<string>> partition(string s) {result.clear();path.clear();backtracking(s,0);return result;}
};

 

参考:代码随想录

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

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

相关文章

python--常用简单功能

os函数获取上层目录 # 获取当前目录 print(os.path.abspath(os.path.dirname(__file__))) # 获取上级目录 print(os.path.abspath(os.path.dirname(os.path.dirname(__file__)))) print(os.path.abspath(os.path.dirname(os.getcwd()))) print(os.path.abspath(os.path.join(o…

execl数据多维度建模(二)

源数据 1.选择数据 1&#xff09;插入透视表 选中源数据的数据区域--插入--数据透视表&#xff08;新的工作表名&#xff1a;透视表&#xff09; 2&#xff09;透视表设置 ShipCountry拉入行标签&#xff1b;CategoryName拉入列标签&#xff1b;sales拉入值的位置 3&#xf…

第八节:Vben Admin登录页面自定义

系列文章目录 第一节:Vben Admin介绍和初次运行 第二节:Vben Admin 登录逻辑梳理和对接后端准备 第三节:Vben Admin登录对接后端login接口 第四节:Vben Admin登录对接后端getUserInfo接口 第五节:Vben Admin权限-前端控制方式 第六节:Vben Admin权限-后端控制方式 第七节…

计算机二级Python题目12

目录 1. 基础题 1.1 基础题1 1.2 基础题2 1.3 基础题3 2. turtle画图题 3. 大题 3.1 大题1 3.2 大题2 1. 基础题 1.1 基础题1 sinput("请输入一个小数&#xff1a;") ss[::-1] cs0 for c in s:if c.:breakcseval(c) print({:*>10}.format(cs)) 1.2 基础…

软考论文写作注意事项

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/136816368 一. 论文要求 1、形式方面的要求。首先&#xff0c;内容要丰满&#xff0c;即字数要够&#xff0c;其中摘要字数为 290&#xff5e;320&#xff0c;正文字数为 2200&#xff5e;2800&#x…

kvm利用脚本创建一个新的虚拟机 —— 筑梦之路

1. 脚本文件 #!/usr/bin/env bash # 创建虚拟机 ## 2021/3/28kvm_install(){set -ueset -o pipefail# 创建相关目录ls /home/kvm/{ks,virtualhost,virtual-img} 1>/dev/null 2>&1 || mkdir -p /home/kvm/{virtualhost,virtual-img}# 此程序的变量KVM_HOME/home/kvmK…

winpcap设备名

接口定义&#xff1a; #include <pcap/pcap.h> char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf);其中的device构造如下&#xff1a; 调用GetAdaptersInfo&#xff0c;返回值中的Adapt…

Linux 系统日志

系统日志类型 /var/log/syslog&#xff1a;系统日志&#xff0c;记录所有系统事件。/var/log/messages&#xff1a;系统消息&#xff0c;记录所有系统消息&#xff0c;包括启动信息、错误和警告信息。/var/log/auth.log&#xff1a;认证日志&#xff0c;记录所有认证事件&…

CPU生产的生命周期 - 原材料篇

CPU是中央处理器的缩写&#xff0c;它是执行程序指令的电子电路。CPU使用的基本原材料是硅、铜、铝和各种塑料。由于CPU在现代社会中被大量消耗&#xff0c;因此生产商必须考虑原材料的能源投入和环境影响。 硅是地壳中第二丰富的元素。它以二氧化硅和硅酸盐的形式存在。二氧化…

Linux——进程通信(二) 匿名管道的应用:进程池

前言 之前我们学习了进程通过匿名管道进行通信&#xff0c;实现了两个进程的数据传输。 如果我们管理的是很多个进程&#xff0c;通过管道发送指令&#xff0c;因为如果管道中没有数据&#xff0c;读端必须等待&#xff0c;也就是被管理的进程们都在等待我发送的指令&#xf…

CVE-2024-24112 XMall后台管理系统 SQL 注入漏洞分析

------作者本科毕业设计项目 基于 Spring Boot Vue 开发而成...... [Affected Component] /item/list /item/listSearch /sys/log /order/list /member/list (need time-based blind injection) /member/list/remove 项目下载地址 Exrick/xmall: 基于SOA架构的分布式…

cesium viewer camera flyto

一、viewer的flyTo内部调用的是camera的相关定位方法&#xff0c;针对不同的定位对象&#xff0c;计算出合适的位置和相机视角。viewer可以定位到entity、dataSource、Cesium3DTileset、ImageLayer等。 var rect [116.490401, 39.964771, 116.499623, 39.977102];var heading …

2024全国水科技大会:【协办单位】山东文远环保科技股份有限公司

山东文远环保科技股份有限公司坐落于千年古城齐国故都--临淄。初始成立于2011年&#xff0c;是淄博市首批国有资本参股的混合改制企业。 公司着力打造环保设备制造、环保工程及服务、环保水务/固废处理/新能源项目投资及运营管理、固废循环经济产业园等四大板块。是一家集投资、…

在https网站中加载http资源

https中加载http资源&#xff0c;如果该资源https也有&#xff0c;直接替换就是&#xff0c;如果没有&#xff0c;如果按照网上的做法大概率是不奏效。言归正传&#xff0c;在一位C友文章中看到了利用nginx来做代理来实现访问http资源之后&#xff0c;我自己也做了尝试。 参考…

Elasticsearch8.x版本Java客户端Elasticsearch Java API 如何并发修改

前言 并发控制&#xff0c;一般有两种方案&#xff0c;悲观锁和乐观锁&#xff0c;其中悲观锁是默认每次更新操作肯定会冲突&#xff0c;所以每次操作都要先获取锁&#xff0c;操作完毕再释放锁&#xff0c;适用于写比较多的场景。而乐观锁是默认每次更新操作都不会冲突&#…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:GridCol)

栅格子组件&#xff0c;必须作为栅格容器组件(GridRow)的子组件使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含单个子组件。 接口 GridCol(option?:{span?: number | …

综合知识篇00-综合知识考点汇总目录(2024年软考高级系统架构设计师冲刺知识点总结-综合知识篇-先导篇)

专栏系列文章推荐&#xff1a; 2024高级系统架构设计师备考资料&#xff08;高频考点&真题&经验&#xff09;https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】&#xff08;2024年软考高级…

差分数组实战——滴滴春招笔试第一题

前言 作者&#xff1a;晓宜 &#x1f308;&#x1f308;&#x1f308; 个人简介&#xff1a;互联网大厂Java准入职&#xff0c;阿里云专家博主&#xff0c;csdn后端优质创作者&#xff0c;算法爱好者 &#x1f319;&#x1f319;&#x1f319; 上周末参与了滴滴的春招笔试&…

二叉树的初步学习和顺序结构实现

当我们学完顺序表、链表、栈和队列的时候&#xff0c;我们就要开始学习树了。树对于以后的学习有非常大的帮助&#xff0c;尤其是排序。好了&#xff0c;开始我们的学习吧。 1.树的概念及结构 1.1树的结构 树结构是一种非线性结构。它是由n&#xff08;n>0&#xff09;个…

CHINC邀请函 | 全视通邀您共赴青岛,碰撞数智火花

展会名称&#xff1a;2024中华医院信息网络大会&#xff08;CHINC&#xff09; 展会时间&#xff1a;3月29-31日 展会地址&#xff1a;青岛国际会展中心&#xff08;红岛馆&#xff09; 全视通展位&#xff1a;B2-A05A 全视通将携智慧病区、智慧门诊、智慧手术室、智慧后勤…