当前位置: 首页 > news >正文

058组合总和

组合总和

题目链接:https://leetcode.cn/problems/combination-sum/description/?envType=study-plan-v2&envId=top-100-liked

我的解答:

public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> ans = new ArrayList<>(); dfs(candidates, target, 0, 0, new ArrayList<>(), ans); return ans; } //startIndex:每次选取的初始位置(我们只需让下一次选取从上一次选取的位置开始,就可避免出现重复组合) public void dfs(int[] candidates, int target, int sum, int startIndex, List<Integer> output, List<List<Integer>> ans){ if(sum == target){ ans.add(new ArrayList<>(output)); return; } if(sum > target){ return; } int length = candidates.length; for(int i=startIndex; i<length; i++){ sum += candidates[i]; output.add(candidates[i]); dfs(candidates, target, sum, i, output, ans); sum -= candidates[i]; output.remove(output.size()-1); } }

分析:

​ 代码的时间复杂度为O(S),其中 S 为所有可行解的长度之和。空间复杂度为O(target),除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target) 层。(本题复杂度我不知道该如何表示,直接看了官方的)

​ 解题思路:采用基本的递归 + 回溯方法,唯一的难点在于如何避免出现重复组合,经过思考我发现,由于candidates是一个无重复元素的整数数组,所以只需让下一次选取从上一次选取的位置开始,就可以避免出现重复组合。

看了官方题解后的解答:

//方法:搜索回溯(官方版) //时间复杂度:O(S),其中 S 为所有可行解的长度之和。 //空间复杂度:O(target),除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target) 层。 public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> ans = new ArrayList<List<Integer>>(); List<Integer> combine = new ArrayList<Integer>(); dfs(candidates, target, ans, combine, 0); return ans; } public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) { if (idx == candidates.length) { return; } if (target == 0) { ans.add(new ArrayList<Integer>(combine)); return; } // 直接跳过 dfs(candidates, target, ans, combine, idx + 1); // 选择当前数 if (target - candidates[idx] >= 0) { combine.add(candidates[idx]); dfs(candidates, target - candidates[idx], ans, combine, idx); combine.remove(combine.size() - 1); } } //方法:搜索回溯(看了官方解答后,对我的解答进行优化版) //时间复杂度:O(S),其中 S 为所有可行解的长度之和。 //空间复杂度:O(target),除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target) 层。 public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> ans = new ArrayList<>(); dfs(candidates, target, 0, new ArrayList<>(), ans); return ans; } //startIndex:每次选取的初始位置(我们只需让下一次选取从上一次选取的位置开始,就可避免出现重复组合,同时进行剪枝) public void dfs(int[] candidates, int target, int startIndex, List<Integer> output, List<List<Integer>> ans){ if(target == 0){ ans.add(new ArrayList<>(output)); return; } int length = candidates.length; for(int i=startIndex; i<length; i++){ if(target - candidates[i] >= 0){ target -= candidates[i]; output.add(candidates[i]); dfs(candidates, target, i, output, ans); target += candidates[i]; output.remove(output.size()-1); } } }

分析:官方的解题思路与我的解答基本一致,但是在剪枝上进行了优化,优化的点在于,每次判断target减去当前选取的数后是否小于0,若小于0则直接跳过这个数。

总结

  • 本题采用基本的递归 + 回溯方法,思路简单,唯一需要思考的是如何进一步进行剪枝优化。
http://www.jsqmd.com/news/884264/

相关文章:

  • Taotoken 的用量看板与成本管理功能如何帮助团队控制 AI 支出
  • 除甲醛怎么选?2026年行业口碑企业推荐指南 - 品牌排行榜
  • Obsidian PDF++解决方案:构建原生双向链接的知识管理生态系统
  • 基于树莓派与ModBus协议实现高端新风系统接入HomeKit智能家居
  • 基于ESP32的智能调酒机:物联网Web服务器与电磁阀控制实践
  • 武商一卡通回收指南:轻松选择回收平台,快速变现 - 团团收购物卡回收
  • 标准混合气体定制找哪类供应商:广东大特气体给两广实验室与检测客户的采购清单 - 华旭传媒
  • 对比直接使用厂商API与通过Taotoken聚合调用的成本体感
  • RFold:通过作业折叠与拓扑重构协同优化AI集群资源调度
  • 微信小程序AR与3D全景开发实战指南:揭秘Three.js在移动端的终极应用
  • 通过curl命令快速测试Taotoken多模型API的连通性与返回格式
  • Skeptical Learning:人机协作式数据清洗框架的原理、实践与挑战
  • Ansys中国区授权伙伴 - 品牌2025
  • FM5057H 二合一锂电池保护 IC
  • RFID手持终端机有哪些功能?选购指南帮你理清需求 - 资讯纵览
  • 2026年成都电缆桥架与抗震支架采购指南:模块化预制如何降低工程成本30%-50% - 优质企业观察收录
  • 【Sora 2 HDR视频生成技术白皮书】:20年AIGC架构师首曝4K/60fps动态色调映射实战参数与避坑清单
  • AlwaysOnTop:5分钟掌握Windows窗口置顶神器,工作效率翻倍!
  • 【Midjourney图像锐化终极指南】:20年AI视觉工程师亲测的7种精准锐化参数组合,避开92%的过冲伪影
  • 图神经网络在粒子径迹重建中的应用:从原理到LHCb实验实践
  • 为什么你需要这个专业工具:3分钟解决艾尔登法环存档迁移难题的终极指南
  • 迁移至 Taotoken 后开发调试过程中 API 可用性的提升感知
  • 终极NS模拟器管理工具:10分钟搭建完整游戏环境
  • DeepSeek大模型幻觉诊断指南:3步定位、4维验证、7天落地防控体系
  • 智谱开启狂飙模式!7倍提速,全球最快,旗舰模型即问即答
  • SuperCom串口调试工具:终极免费解决方案与5分钟快速部署指南
  • 2026哥大生物医学信息学求职:蒸汽教育TPS体系 - 资讯纵览
  • 对比直接使用厂商api体验taotoken在路由容灾方面的优势
  • 别再花钱买云服务了!手把手教你在Windows 10上用Nginx搭个免费的RTMP直播服务器
  • 网络软文发布平台怎么选?网络软文发布平台最佳性价比平台 - 代码非世界