首先,如果您使用的是Java 8,那么 List list 的求和就像 list.stream().mapToInt(n -> n).sum() 一样简单 .
其次,递归总是采用类似的形式:
func(context)
if context in simple form
return simple result
else
break context down into smaller pieces
call func on smaller pieces
在你的情况下,它看起来像
func(total, list)
if sum(list) == total
return list
else if list is not empty
get all solutions from func(total - first item, list without first item)
and func(total, list without first item)
这里有一些棘手的事情需要考虑:
如何处理返回列表以及它是否是有效结果
如何删除项目,然后在递归调用后将其添加回来
这是一个带有测试用例的示例解决方案 .
public class ListSum {
public static void main(String[] args) {
subsetsThatSumTo(18, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)).forEach(System.out::println);
}
public static List> subsetsThatSumTo(int total, List list) {
List> result = new ArrayList<>();
if (list.stream().mapToInt(n -> n).sum() == total) {
result.add(new ArrayList<>(list));
} else if (!list.isEmpty()) {
subsetsThatSumTo(total - list.get(0), list.subList(1, list.size())).forEach(result::add);
result.forEach(l -> l.add(0, list.get(0)));
subsetsThatSumTo(total, list.subList(1, list.size())).forEach(result::add);
}
return result;
}
}
如果您只想返回第一个结果:
public class ListSum {
public static void main(String[] args) {
System.out.println(subsetThatSumTo(18, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)));
}
public static List subsetThatSumTo(int total, List list) {
if (list.stream().mapToInt(n -> n).sum() == total)
return new ArrayList<>(list);
if (list.isEmpty())
return null;
List result = subsetThatSumTo(total - list.get(0), list.subList(1, list.size()));
if (result != null) {
result.add(0, list.get(0));
return result;
} else {
return subsetThatSumTo(total, list.subList(1, list.size()));
}
}
}