import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 题目:
* 组合总和 -- leetcode 39
* <p>
* 题目描述:
* <p>
* 给定一个无重复元素的数组 candidates 和一个目标数 target ,
* 找出 candidates 中所有可以使数字和为 target 的组合。
* candidates 中的数字可以无限制重复被选取。
* <p>
* 说明:
* 所有数字(包括 target)都是正整数。
* 解集不能包含重复的组合。
* <p>
* 示例 1:
* 输入: candidates = [2,3,6,7], target = 7,
* 所求解集为:
* [
* [7],
* [2,2,3]
* ]
* <p>
* 示例 2:
* 输入: candidates = [2,3,5], target = 8,
* 所求解集为:
* [
* [2,2,2,2],
* [2,3,3],
* [3,5]
* ]
*/
public class CombinationSum {
public static void main(String[] args) {
{
int[] candidates = new int[]{2, 3, 5};
int target = 8;
System.out.println(combinationSum(candidates, target));
System.out.println(combinationSumII(candidates, target));
}
{
int[] candidates = new int[]{2, 3, 6, 7};
int target = 7;
System.out.println(combinationSum(candidates, target));
System.out.println(combinationSumII(candidates, target));
}
}
/**
* https://www.jianshu.com/p/42211be17acb
* 思路:
* 1、回溯算法
* 2、递归找和为target的组合,出口为和超过了target
*/
public static List<List<Integer>> combinationSum(int[] arr, int target) {
List<List<Integer>> res = new ArrayList<>();
if (arr == null) {
return res;
}
addCombinations(arr, 0, target, new ArrayList<>(), res);
return res;
}
private static void addCombinations(int[] arr,
int start,
int target,
List<Integer> cache,
List<List<Integer>> res) {
if (target < 0) {
return;
}
if (target == 0) {
res.add(new ArrayList<>(cache));
return;
}
for (int i = start; i < arr.length; i++) {
cache.add(arr[i]);
addCombinations(arr, i, target - arr[i], cache, res);
cache.remove(cache.size() - 1);
}
}
/**
* https://www.jianshu.com/p/42211be17acb
* 思路:
* 优化后的回溯
*/
public static List<List<Integer>> combinationSumII(int[] arr, int target) {
List<List<Integer>> res = new ArrayList<>();
if (arr == null) {
return res;
}
// 排序数组后 可以在递归的时候减少递归次数,配合 if (arr[i] > target) break;
Arrays.sort(arr);
addCombinationsII(arr, 0, target, new ArrayList<>(), res);
return res;
}
private static void addCombinationsII(int[] arr,
int start,
int target,
List<Integer> cache,
List<List<Integer>> res) {
if (target < 0) {
return;
}
if (target == 0) {
res.add(new ArrayList<>(cache));
return;
}
for (int i = start; i < arr.length; i++) {
// 配合排序后的数组 提升性能
if (arr[i] > target) {
break;
}
cache.add(arr[i]);
addCombinationsII(arr, i, target - arr[i], cache, res);
cache.remove(cache.size() - 1);
}
}
}
leetcode 39 : 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
最新推荐文章于 2024-09-27 13:05:29 发布