题目描述

给定一个无重复的正整数数组 candidates 和一个正整数 target, 求所有和为 target 的 candidates 中数的组合中。其中相同数的不同顺序组合算做同一种组合,candidates 中的数可以重复使用。

算法一

首先想到的方法就是枚举所有的组合可能性,判断其和是否为target。枚举的方法可以使用递归,对candidates中每一个数,有“加入组合”和“不加入组合”两种选择,每一种选择又可以向后面元素的不同选择递归,直到candidate中最后一个元素。可以用剪枝来减少算法的运行时间,如果当前组合的和大于target,则当前情形下已不会有合适的组合了。
AC代码如下:
class Solution {public List<List<Integer>> combinationSum(int[] candidates, int target) {List<List<Integer>> res = new ArrayList<List<Integer>>();dfs(candidates, 0, target, new ArrayList<Integer>(), res);return res;}private void dfs(int[] candidates, int index, int target, List<Integer> combination, List<List<Integer>> res) {if(target < 0) return;if(target == 0) {res.add(new ArrayList<>(combination));return;}for(int i=index; i<candidates.length; i++) {if(candidates[i] > target) continue;//选择当前元素
            combination.add(candidates[i]);dfs(candidates, i, target - candidates[i], combination, res);//不选择当前元素combination.remove(combination.size() - 1);}}
}

算法二

本题符合动态规划的思想,用一个map记录不同target的全部组合,target <=  0的组合为空, target = i的组合为全部 target = i - candidates[j] (0<j<candidates.length)的组合加上candidates[j]。
这里需要注意,因为题目要求相同元素的不同顺序算同一种组合方式,上诉方法会出现[2,3,2] 和 [2,2,3]这样两种组合方式。可以用将每一种组合排序后加入set的方法来去重。
AC代码:
class Solution {public List<List<Integer>> combinationSum(int[] candidates, int target) {Map<Integer, List<List<Integer>>> dp = new HashMap<Integer, List<List<Integer>>>();return dp(target, 0, candidates, dp);}private List<List<Integer>> dp(int target, int index, int[] candidates, Map<Integer, List<List<Integer>>> map){if(map.containsKey(target)) {return map.get(target);}List<List<Integer>> resList = new ArrayList<>();Set<List<Integer>> resSet = new HashSet<>();//这里一定要能够区分出 小于0和等于0.       等于0时加一个空的,避免出现[2,3,6,7] ,target = 7时,6被放入其中!!!!if(target < 0 ) return resList;if(target == 0){resList.add(new ArrayList<>());return resList;}for(int i=index; i<candidates.length; i++){List<List<Integer>> subResList = dp(target - candidates[i], index, candidates, map);if(subResList.size() > 0) {for(List<Integer> subRes : subResList) {List<Integer> res = new ArrayList<>(subRes);res.add(candidates[i]);Collections.sort(res);resSet.add(res);}}}for(List<Integer> l : resSet) {resList.add(l);}map.put(target, resList);return resList;}
}

算法三

本题还可以采用背包问题的思想,target相当于背包的容量,candidates为物品。
用一个map记录sum的范围从0~target的所有组合,容量为 i 的组合求解方式如下:遍历每一个物品candidates[j], 获取容量为 i - candidates[j]的所有组合,加入该物品。
这里值得注意的是,因为题目要求相同元素的不同顺序算同一种组合方式,因此需要将物品的循环放在容量循环的外面,这样就可以避免出现重复出现[2,3,2] 和 [2,2,3]这样两种组合方式。
AC代码:
class Solution {public List<List<Integer>> combinationSum(int[] candidates, int target) {Map<Integer, List<List<Integer>>> m = new HashMap<>();m.put(0, new ArrayList<List<Integer>>());for(int i=0; i<candidates.length; i++){for(int j=0; j<=target; j++){if(j < candidates[i]) continue;List<List<Integer>> l = m.get(j - candidates[i]);if(l != null) {List<List<Integer>> jList = m.getOrDefault(j, new ArrayList<List<Integer>>());if(l.size() == 0){List<Integer> lcurr = new ArrayList<>();lcurr.add(candidates[i]);jList.add(lcurr);}else{for(List<Integer> listInL : l){List<Integer> lcurr = new ArrayList<>(listInL);lcurr.add(candidates[i]);jList.add(lcurr);}}m.put(j, jList);}}}return m.getOrDefault(target, new ArrayList<List<Integer>>());}
}

转载于:https://www.cnblogs.com/NelsonProgram/p/10715410.html

LeetCode笔记:39. Combination Sum相关推荐

  1. 【DFS】LeetCode 39. Combination Sum

    LeetCode 39. Combination Sum Solution1: DFS,这个套路要熟记啊! class Solution { public:vector<vector<in ...

  2. leetcode 39. Combination Sum | 39. 组合总和(Java)

    题目 https://leetcode.com/problems/combination-sum/ 题解 不是最优解法. 对于每一个位置 i 上 的元素,分为选或不选两种情况. 遍历每一个位置,计算强 ...

  3. 39. Combination Sum

    description: 给定target, 求给定数列中找到几个数(其中的数可以重复使用,且一组数有几个也不做限制)的和为target Note: https://www.cnblogs.com/g ...

  4. LeetCode OJ:Combination Sum III(组合之和III)

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  5. 39. Combination Sum 组合总和

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

  6. 40. Combination Sum II 组合总和 II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...

  7. 【LeetCode】#39组合总和(Combination Sum)

    [LeetCode]#39组合总和(Combination Sum) 加粗样式 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数 ...

  8. 【动态规划】LeetCode 377. Combination Sum IV

    LeetCode 377. Combination Sum IV Solution1: 我的未能AC的答案 题目描述的和前几道题差不多,但实际上不能用DFS来做(会超时),要用动态规划,还是记录一下吧 ...

  9. LeetCode笔记:Biweekly Contest 85

    LeetCode笔记:Biweekly Contest 85 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

最新文章

  1. java B2B2C源码电子商城系统:服务消费(基础)
  2. 解决Fiddler不能监听Java HttpURLConnection请求的方法
  3. 第三章 达瑞,一个很能挣钱的男孩
  4. “高级”数据结构——树状数组
  5. Django框架使用
  6. 第一篇:SpringCloud 构建微服务系统之服务注册和发现(consul)
  7. ASP.NET Core MVC 源码学习:MVC 启动流程详解
  8. jquery/原生js/css3 实现瀑布流以及下拉底部加载
  9. codeforces-148D-Bag of mice-概率DP
  10. 骁龙855加持!OPPO Reno正面照揭晓:边框窄得吓人
  11. python文件命名 数字,当文件存在时,文件名中的数字递增
  12. 放在请求头目的_YSLOW性能测试前端调优23大规则(三)添加Expires头
  13. [转]ios面试题收集(二)
  14. 古墓新手机器人_古墓新手任务攻略 - 玩家乐园 - 北大侠客行MUD论坛 - Powered by Discuz!...
  15. java后端使用itextPDF生成PDF文件
  16. python制作照片_python3一键排版证件照(一寸照、二寸照),附源代码
  17. Chrome插件开发(chrome-extension)
  18. 小米用户画像_华为小米OPPOvivo用户画像,用户兴趣爱好各有不同!还有一大相同点!...
  19. 最齐全的文化石 艺术石VRay材质球素材,速来收藏
  20. 为什么社区团购需要小程序?

热门文章

  1. 【073】Android 数据存储(SQLite)
  2. C#程序设计语言2.0简介
  3. Jmeter之Synchronizing Timer(同步集合点)
  4. 如何不让你的APP在模拟器中运行。
  5. Linux内存实际使用率
  6. CISCO路由器的备份与还原(1)
  7. php-5.6配置,PHP5.6+apache2.4环境配置
  8. tcp udp区别优缺点_TCP和UDP的区别
  9. MFileServer管理员用户名密码配置
  10. ActiveMQ使用线程池实现消息的生产与消费