Combination Sum系列问题
主要使用方法是backtracking。
Combination Sum
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is: [7] [2, 2, 3]
解答:为了减少许多不必要的循环过程,应该先把candidates排序,这样当目前遍历到的元素和已经大于target时,就可以不必再访问candidates后面的元素,直接退回到上个选择处进行选择。
另外,由于candidates集合中的每个数都可以使用无数次,故每次递归调用都应该从上次加入的元素开始遍历。
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if (candidates == null || candidates.length == 0) {
return result;
}
Arrays.sort(candidates);
List<Integer> temp = new LinkedList<Integer>();
helper(candidates, target, result, temp, 0);
return result;
}
public void helper (int[] candidates, int target, List<List<Integer>> result, List<Integer> temp, int index) {
if (target == 0) {
result.add(new LinkedList<Integer>(temp));
return;
}
for (int i = index; i < candidates.length && candidates[i] <= target; i++) {
temp.add(candidates[i]);
helper(candidates, target - candidates[i], result, temp, i); //从上次加入的元素开始遍历
temp.remove(temp.size() - 1);
}
}
}
Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is: [1, 7] [1, 2, 5] [2, 6] [1, 1, 6]
解答:与上题一样应该先把candidates排序。
这题需要注意的有两点是:
1. 每个元素只能用一次,所以每次递归都应该从当前加入元素的下一个元素开始遍历;
2. 集合中含有重复元素,所以在每次for循环在candidates挑选元素时,应将已经挑选过的元素过滤(因为加入此元素的结果已经加入结果集合),避免集合中结果出现重复。递归中则不用考虑起始点与上个元素是否相同,因为递归是在前面元素确定的情况下加入下一元素,它们在同一结果中。
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> rst = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
helper(rst, temp, candidates, target, 0);
return rst;
}
public void helper(List<List<Integer>> rst, List<Integer> temp, int[] candidates, int target, int index) {
if (target == 0) {
rst.add(new ArrayList<Integer>(temp));
return;
}
for (int i = index; i < candidates.length && candidates[i] <= target; i++) {
if (i > index && candidates[i] == candidates[i - 1]) {
continue;
}
temp.add(candidates[i]);
helper(rst, temp, candidates, target - candidates[i], i + 1); //从下一个元素开始遍历
temp.remove(temp.size() - 1);
}
}
}
Combination Sum III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Ensure that numbers within the set are sorted in ascending order.
Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]]
解答:可以看做是上题的一种特殊情况, candidates数组中的元素为1到9,且不含重复元素,上题中去重的判断可以去掉。
public class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
helper(rst, temp, k, n, 1);
return rst;
}
public void helper(List<List<Integer>> rst, List<Integer> temp, int k, int n, int number) {
if (k == temp.size() && n == 0) {
rst.add(new ArrayList<Integer>(temp));
return;
}
for (int i = number; i <= 9 && i <= n; i++) {
temp.add(i);
helper(rst, temp, k, n - i, i + 1);
temp.remove(temp.size() - 1);
}
}
}
总结:本题需要注意的是每次递归里面的循环起始点,以及如何避免结果集的重复。
Combination Sum系列问题的更多相关文章
- [Leetcode] Combination Sum 系列
Combination Sum 系列题解 题目来源:https://leetcode.com/problems/combination-sum/description/ Description Giv ...
- Leetcode 之 Combination Sum系列
39. Combination Sum 1.Problem Find all possible combinations of k numbers that add up to a number n, ...
- 子集系列(二) 满足特定要求的子集,例 [LeetCode] Combination, Combination Sum I, II
引言 既上一篇 子集系列(一) 后,这里我们接着讨论带有附加条件的子集求解方法. 这类题目也是求子集,只不过不是返回所有的自己,而往往是要求返回满足一定要求的子集. 解这种类型的题目,其思路可以在上一 ...
- [LeetCode] Combination Sum IV 组合之和之四
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- [LeetCode] Combination Sum III 组合之和之三
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
- 从Leetcode的Combination Sum系列谈起回溯法
在LeetCode上面有一组非常经典的题型--Combination Sum,从1到4.其实就是类似于给定一个数组和一个整数,然后求数组里面哪几个数的组合相加结果为给定的整数.在这个题型系列中,1.2 ...
- 【一天一道LeetCode】#40. Combination Sum II
一天一道LeetCode系列 (一)题目 Given a collection of candidate numbers (C) and a target number (T), find all u ...
- 39. Combination Sum + 40. Combination Sum II + 216. Combination Sum III + 377. Combination Sum IV
▶ 给定一个数组 和一个目标值.从该数组中选出若干项(项数不定),使他们的和等于目标值. ▶ 36. 数组元素无重复 ● 代码,初版,19 ms .从底向上的动态规划,但是转移方程比较智障(将待求数分 ...
- [LeetCode] 377. Combination Sum IV 组合之和之四
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
随机推荐
- 获取div滚动条的宽度
获取滚动条的宽度: function getScrollWidth() { var noScroll, scroll, oDiv = document.createElement('div'); oD ...
- 谈JS中的作用域链与原型链(1)
学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...
- java生成二维码
具体代码如下,作为一个新手,期待与你一起交流: import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.Buf ...
- jsp的九大内置对象和四个作用域
request 请求对象 类型 javax.servlet.ServletRequest 作用域 Request response ...
- 《Django By Example》第七章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:咳咳,第七章终于来了.其 ...
- UVALive 7045 Last Defence
ProblemK. Last Defence Description Given two integersA and B. Sequence S is defined as follow: • S0 ...
- SVN 中trunk、branches、tags的详解
1.trunk是主分支,是日常开发进行的地方.2.branches是分支.一些阶段性的release版本,这些版本是可以继续进行开发和维护的,则放在branches目录中.又比如为不同用户客制化的版本 ...
- Gradle之恋-任务1
任务作为Gradle的核心功能模块,而且Gradle的任务还可以具有自己的属性和方法,大大扩展了Ant任务的功能.由于任务相关内容比较多,分为两篇来探讨,本篇主要涉及到:任务的定义.任务的属性.任务的 ...
- 用一个jsp实现对数据库发访问
<%@ page language="java" import="java.util.*" pageEncoding="gb2312" ...
- 10分钟精通SharePoint - SharePoint拓扑结构
SharePoint服务器角色:前端,应用程序和数据库服务器 应用程序服务:搜索.Office文档.User Profile和App等应用服务器 数据库类型:内容数据库.应用程序数据库和配置数据库 规 ...