代码随想录Day29

39.组合总和

题目:39. 组合总和 - 力扣(LeetCode)

思路:可以重复选取,这个要怎么回溯?而且是无限制的重复。每次回溯,都还是遍历当前的数组,记住数组中的最小值,一旦发现path的值加上最小值大于目标值,直接return,

尝试
class Solution {List<List<Integer>> result= new ArrayList<>();List<Integer> path = new ArrayList<>();int min = Integer.MAX_VALUE;int sum = 0;public List<List<Integer>> combinationSum(int[] candidates, int target) {for(int i : candidates){if(i < min) min = i;}backTracking(candidates,target,sum);return result;}public void backTracking(int[] candidates, int target,int sum){if(sum == target ){// result.add(path);result.add(new ArrayList<>(path));return;}if(sum > target){return;}for(int i = 0;i < candidates.length;i++){sum += candidates[i];path.add(candidates[i]);backTracking(candidates,target,sum);path.remove(path.size()-1);sum -=candidates[i];  }}
}

🍉返回结果时,要用【 result.add(new ArrayList<>(path));】 

🍉我尝试中出现的问题是,会有【2,2,3】【2,3,2】这样的重复组合

答案
// 剪枝优化
class Solution {List<List<Integer>> res = new ArrayList<>();List<Integer> path = new  ArrayList<>();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.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素}}
}
小结

🍉对于组合问题,如果是一个集合来求组合的话,就需要startIndex,多个集合取组合,各个集合之间相互不影响,那么就不用startIndex

🍉终止遍历,用break

if (sum + candidates[i] > target) break;

🍉递归函数的参数【idx】,作用就是防止组合重复,如下图,取【2】之后,可以在【2,3,5】中接着取,但是取【5】之后只能在【5,3】中接着取

40.组合总和||

题目:40. 组合总和 II - 力扣(LeetCode)

思路:跟组合总和应该是类似的,只能使用一次,注意candidate里面有重复元素,搞一个指针,不断移动地去加,这样就能保证一个元素只被用了一次,怎么实现在同一个path下移动指针,感觉现在需要两个指针

尝试
class Solution {List<List<Integer>> result = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);backTracking(candidates,target,0,0);return result;}public void backTracking(int[] candidates, int target,int sum,int idx){if(sum == target){result.add(new ArrayList<>(path));}for(int i = idx; i < candidates.length; i++){if(sum +candidates[i] > target) break;path.add(candidates[i]);backTracking(candidates,target,sum + candidates[i],i+1);path.remove(path.size() - 1);}}
}

出现了重复组合,关键还是不知道怎么移动指针 

 修改(我靠,加一个if函数就AC了)
class Solution {List<List<Integer>> result = new ArrayList<>();List<Integer> path = new ArrayList<>();public List<List<Integer>> combinationSum2(int[] candidates, int target) {Arrays.sort(candidates);backTracking(candidates,target,0,0);return result;}public void backTracking(int[] candidates, int target,int sum,int idx){if(sum == target){result.add(new ArrayList<>(path));}for(int i = idx; i < candidates.length; i++){if(sum +candidates[i] > target) break;if (i > idx && candidates[i] == candidates[i - 1]) {continue;}path.add(candidates[i]);backTracking(candidates,target,sum + candidates[i],i+1);path.remove(path.size() - 1);}}
}
答案
class Solution {List<List<Integer>> res = new ArrayList<>();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;}private void backTracking( int[] candidates, int target, int start ) {if ( sum == target ) {res.add( new ArrayList<>( path ) );return;}for ( int i = start; i < candidates.length && sum + candidates[i] <= target; i++ ) {//正确剔除重复解的办法//跳过同一树层使用过的元素if ( i > start && candidates[i] == candidates[i - 1] ) {continue;}sum += candidates[i];path.add( candidates[i] );// i+1 代表当前组内元素只选取一次backTracking( candidates, target, i + 1 );int temp = path.getLast();sum -= temp;path.removeLast();}}
}
小结

🍉现在明白了,【for循环】是横向遍历,【递归】是纵向遍历

 🍉【for循环】时,每个数字是不能重复的,比如【1,1,2,3】,target为【3】,树层不去重,就会出现两个【1,2】

131.分割回文串

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

思路:印象中回文串要用双指针,为啥感觉遍历就行,回溯干啥啊,难在回溯时,还要判断截取的内容是否回文

答案
class Solution {List<List<String>> lists = new ArrayList<>();Deque<String> deque = new LinkedList<>();public List<List<String>> partition(String s) {backTracking(s, 0);return lists;}private void backTracking(String s, int startIndex) {//如果起始位置大于s的大小,说明找到了一组分割方案if (startIndex >= s.length()) {lists.add(new ArrayList(deque));return;}for (int i = startIndex; i < s.length(); i++) {//如果是回文子串,则记录if (isPalindrome(s, startIndex, i)) {String str = s.substring(startIndex, i + 1);deque.addLast(str);} else {continue;}//起始位置后移,保证不重复backTracking(s, i + 1);deque.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;}
}
小结

 🍉因为对于一个集合,存在多种分割方案,所以要用回溯

🍉【subString】要传入的是(起始位置指针),以及(结尾指针+1)

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

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

相关文章

低成本、功能强大!德思特提供一体化WiFi 6E信道测试方案!

​ 作者介绍 一、方案介绍 伴随WiFi 6E与WiFi 7的提出&#xff0c;WIFI划分出一个全新的5.925GHz-7.125GHz 之间的80MHz和160MHz频段。1200MHz的带宽是迄今为止最宽的&#xff0c;是之前2.4GHz和5GHz WiFi 频段可用带宽的数倍。此外WiFi 6E引入了以下技术&#xff1a; ● 多…

Google I/O 2024:探索未来AI技术的无限可能

近日&#xff0c;Google I/O 2024大会圆满落幕&#xff0c;带给我们一场关于人工智能的盛宴。在这场大会上&#xff0c;Google推出了一系列令人激动的AI新功能和工具&#xff0c;让我们得以一窥未来的科技发展。今天&#xff0c;就让我来为大家总结一下这些亮点吧&#xff01; …

实验室无法培养的菌,原来可以这么研究!

厌氧氨氧化&#xff08;anammox&#xff09;细菌在全球氮循环和废水氮去除中发挥着至关重要的作用&#xff0c;由于anammox细菌生长缓慢、难以培养等特点&#xff0c;对其生态学和生物学特性知之甚少。近日&#xff0c;凌恩生物合作客户重庆大学陈猷鹏教授团队在《Science of t…

802.1X认证,梦回网吧的年代。

1、802.1x的原理 &#xff08;1&#xff09;802.1x的产生原因 802.1X协议作为局域网接口的一个普通接入控制机制在以太网中被广泛应用&#xff0c;主要解决以太网内认证和安全方面的问题。802.1X协议是一种基于接口的网络接入控制协议。“基于接口的网络接入控制”是指&#…

LearnOpenGL(十八)之面剔除

一、面剔除 对于一个3D立方体&#xff0c;无论我们从哪个方向&#xff0c;最多只能同时看到3个面。如果我们能够以某种方式丢弃另外几个看不见的面&#xff0c;我们就能省下超过50%的片段着色器执行数&#xff01; 这正是面剔除(Face Culling)所做的。OpenGL能够检查所有面向…

揭秘未来工厂核心:智慧大屏引领可视化管理新潮流

在数字化浪潮席卷全球的今天&#xff0c;智慧工厂已不再是科幻小说中的概念&#xff0c;而是成为了现代工业发展的新引擎。 智慧工厂可视化大屏&#xff0c;不仅仅是一块显示屏&#xff0c;更是工厂运行的“大脑”。通过这块屏幕&#xff0c;我们可以实时掌握工厂的每一个角落、…

根据参考风格进行矢量图绘制

摘要 利用机器学习根据给定的文本描述生成图像的技术已经取得了显著的进步&#xff0c;例如CLIP图像-文本编码器模型的发布&#xff1b;然而&#xff0c;当前的方法缺乏对生成图像风格的艺术控制。我们提出了一种方法&#xff0c;用于为给定的文本描述生成指定风格的绘图&…

华焰天下晋升质量管理三大体系和产品3C认证实力级

华焰天下&#xff0c;作为业界领先的新能源灶具企业&#xff0c;一直以来都致力于追求卓越的质量管理和产品创新。近日&#xff0c;华焰天下成功晋升为质量管理三大体系先进管理&#xff0c;并成功获得了产品3C认证&#xff0c;这标志着我们在质量管理和产品安全方面迈出了坚实…

【文献阅读】李井林等2021ESG促企业绩效的机制研究——基于企业创新的视角

ESG促进企业绩效的机制 摘要 0.引言与文献综述 1.理论分析与研究假设 1.1企业ESG表现与企业绩效 假设1a&#xff1a;企业的环境表现对企业绩效存在正向影响效应。 假设1b&#xff1a;企业的社会表现对企业绩效存在正向影响效应。 假设1c&#xff1a;企业的公司治理表现对企业…

NGM-SLAM:首创融合神经辐射场子图的3DGS-SLAM,问鼎SOTA!

论文标题&#xff1a; NGM-SLAM: Gaussian Splatting SLAM with Radiance Field Submap 论文作者&#xff1a; Mingrui Li, Jingwei Huang, Lei Sun Aaron, Xuxiang Tian, Tianchen Deng, Hongyu Wang 导读&#xff1a; 3DGS技术因其性能卓越而备受关注&#xff0c;3DGS-SLA…

免费泛域名证书申请

通配符证书是一种 SSL/TLS 证书&#xff0c;可用于保护多个域&#xff08;主机&#xff09;&#xff0c;由域名字段中的通配符 (*) 指示。 如果您有很多需要保护的域或子域&#xff0c;这会很有帮助&#xff0c;因为它可以节省您的时间和金钱。 本文将讨论通配符证书、它们的工…

RAW转换和图像编辑工具:Capture One 23 Pro (win/mac)中文专业版

Capture One 23是一款功能强大的桌面版照片编辑软件&#xff0c;由丹麦PHASE ONE飞思数码公司开发。 以下是该软件的一些主要特点&#xff1a; 强大的RAW处理功能&#xff1a;Capture One 23支持多种品牌的相机和镜头&#xff0c;提供了丰富的RAW处理工具&#xff0c;包括曝光、…