1.给定序列M求解和为N的指定个数为p的所有子系列(不指定p时则将size的条件判断去掉即可获取全部系列)
适用算法:动态规划
如:1, 2, 1, 3, 4, 5, 8, 10, 20, 7, 6, 5, 3
指定长度3:
[[1, 2, 5], [1, 2, 5], [1, 1, 6], [1, 3, 4], [1, 4, 3], [2, 1, 5], [2, 1, 5], [2, 3, 3], [1, 3, 4], [1, 4, 3]]
长度4:
[[1, 2, 1, 4], [1, 1, 3, 3]]
长度为2
[[1, 7], [2, 6], [1, 7], [3, 5], [3, 5], [5, 3], [5, 3]]
算法实现如下:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* description:
*/
public class SumN {
//结果集
public static List<List<Integer>> res = new LinkedList<>();
public static void main(String[] args) {
LinkedList<Integer> integers = new LinkedList<>(Arrays.asList(1, 2, 1, 3, 4, 5, 8, 10, 20, 7, 6, 5, 3));
backTrack(integers, new LinkedList<>(), 0, 3, 8);
System.out.println(res);
}
/**
* 动态规划算法
*
* @param data
* @param track
* @param num 起始索引
* @param size 指定大小
* @param sum 指定和
*/
public static void backTrack(LinkedList<Integer> data, LinkedList<Integer> track, int num, int size, int sum) {
if (track != null && track.stream().mapToInt(o -> o).sum() == sum && track.size() == size) {
res.add(new LinkedList<>(track));
return;
}
//过滤条件
if (track.stream().mapToInt(o -> o).sum() > sum || track.size() > size) {
return;
}
for (int i = num; i < data.size(); i++) {
if (track.stream().mapToInt(o -> o).sum() > sum || track.size() > size) {
continue;
}
track.add(data.get(i));
backTrack(data, track, i + 1, size, sum);
track.removeLast();
}
}
}
大致思路如下:
核心:每选取一个数据,那么下一层决策开始的地方则从i+1开始 避免重复决策