题目:
找出[2,3,4,7]中所有组合target=7
example:[3,4]、[7]
注意:元素可以多次被使用,即[2,2,3]也可以即2可以被使用2
/**
* Author:m
* Date: 2023/04/08 10:46
*/
public class Target7AllowRepeat {
private static final int TARGET = 7;
public static void main(String[] args) {
int[] array = new int[]{2, 3, 4, 7};
List<List<Integer>> result = dfs(array);
System.out.println(result);
}
private static List<List<Integer>> dfs(int[] array) {
if (array == null) {
return Lists.newArrayList();
}
List<List<Integer>> result = Lists.newArrayList();
List<Integer> combine = Lists.newArrayList();
int initIndex = 0;
int sum = 0;
recursion(result, combine, array, initIndex, sum);
return result;
}
private static void recursion(List<List<Integer>> result, List<Integer> combine, int[] array, int initIndex, Integer sum) {
// 1.终止条件
if (sum > TARGET) {
return;
}
// 2.小集合添加至大集合
if (sum == TARGET) {
result.add(Lists.newArrayList(combine));
return;//sum已经等于target了,以tempList为基础的元素再去结合别的元素求和,只会越来越大于target,无需继续了
}
// 3.for循环
for (int i = initIndex; i < array.length; i++) {
// 3.1添加元素到小集合
combine.add(array[i]);
// 3.2递归(由于每一个元素可以重复使用,下一轮搜索的起点依然是 i,而不是i+1)
recursion(result, combine, array, i, sum + array[i]);
// 3.3回溯(小集合删除最后一个元素)
combine.remove(combine.size() - 1);
}
}
}
优化
/**
* Author:m
* Date: 2023/04/08 10:53
*/
public class Target7AllowRepeatOptm {
private static final int TARGET = 7;
public static void main(String[] args) {
int[] array = new int[]{2, 3, 3, 4, 7};
Arrays.sort(array);
List<List<Integer>> result = dfs(array);
System.out.println(result);
}
private static List<List<Integer>> dfs(int[] array) {
if (array == null) {
return Lists.newArrayList();
}
List<List<Integer>> result = Lists.newArrayList();
List<Integer> combine = Lists.newArrayList();
int initIndex = 0;
int sum = 0;
recursion(result, combine, array, initIndex, sum);
return result;
}
private static void recursion(List<List<Integer>> result, List<Integer> combine, int[] array, int initIndex, Integer sum) {
// 1.终止条件
if (sum > TARGET) {
return;
}
// 2.小集合添加至大集合
if (sum == TARGET) {
result.add(Lists.newArrayList(combine));
return;//sum已经等于target了,以tempList为基础的元素再去结合别的元素求和,只会越来越大于target,无需继续了
}
// 3.for循环
for (int i = initIndex; i < array.length; i++) {
// 3.0剪枝优化
// 如果当前sum = 4,array[i] = 5, 那么sum + 5 > 7了。array是正序排序过的,后面的值只会越来愈大,sum加上他们只会比7更大,不可能为7了
if (sum + array[i] > TARGET) {
break;
}
// 3.1添加元素到小集合
combine.add(array[i]);
// 3.2递归(由于每一个元素可以重复使用,下一轮搜索的起点依然是 i,而不是i+1)
recursion(result, combine, array, i, sum + array[i]);
// 3.3回溯(小集合删除最后一个元素)
combine.remove(combine.size() - 1);
}
}
}