多变量的递归1--多位数字之和为一个定值,且每个数位上的数字也有一个固定的范围
题目是这样的 有1<=n<=8个长度的固定数组,这个数组里面每个数值范围为 0<=m<=9, 如果要这个固定数组每个数字之和为 sum, 0<=sum<=72, 请把数组中组成的所有整数打印出来
import java.util.*;
public class TestRecursiveA {
public static Set<Integer> oneByone(int n, int sum, int m) {
Set<Integer> res = new HashSet<>();
// 创建用于存储当前组合的数组
int[] numComps = new int[n];
// 调用递归回溯方法
backtrack(numComps, 0, 0, sum, m, res);
return res;
}
private static void backtrack(int[] numComps, int index, int currentSum, int target, int m, Set<Integer> res) {
// 如果已填充所有位置
if (index == numComps.length) {
// 检查当前组合的总和是否等于目标工作时间
if (currentSum == target) {
// 将数组转换为整数并添加到结果集
int num = 0;
for (int value : numComps) {
num = num * 10 + value;
}
res.add(num);
}
return;
}
// 尝试当前所有可能的数字
for (int h = 0; h <= m; h++) {
int newSum = currentSum + h;
// 剪枝:如果当前总和已超过目标,提前终止
//为什么这儿是break,因为比当前h 大的数必然导致newSum > m
if (newSum > m) {
break;
}
// 剪枝:如果剩余位置即使填充最大值仍不足,跳过当前尝试
//为什么这儿是continue,因为就是h太小,导致即使后面全加上最大的数的和都还是不够,还要在这个循环里找更大的h,这样便于找到合适的数
if (newSum + (numComps.length - index - 1) * m < target) {
continue;
}
// 设置当前值并递归处理下一个位置
numComps[index] = h;
backtrack(numComps, index + 1, newSum, target, m, res);
}
}
public static void main(String[] args) {
// 示例用法
Set<Integer> result = oneByone(5, 10, 3);
System.out.println(result);
}
}
浙公网安备 33010602011771号