递归求解子集和问题的思路
子集和问题:
给定一个集合S和一个目标值t,求问是否能从S中找出一个子集,使得这个子集元素之和等于目标值t
假设有一个集合S = {-1, 2, 7, 10},一个目标值t = 8。那么我们可以找到S的一个子集S1 = {-1, 2, 7} 各项之和等于8。
解决子集和问题的基本思路是 The inclusion/exclusion pattern,即判断某个元素element是否应该被包含在组成目标值的子集和中。如果子集和问题有解,一般有两种方式来处理这个元素:该元素被包含,那么集合S剩下的元素可以组成t - element ;该元素被排除,那么集合S剩下的元素可以组成t。
因此函数可写为:
bool subsetSumExists(set<int> &s, int target){
if (set.isEmpty()) {
return target==0;
} else {
int element = s.first();
set<int> rest = s - element;
return subsetSumExists(rest, tartget) ||
subsetSumExists(rest, target-element);
}
}
最基本的情况是当集合为空集时,只有目标值为0才可能。后面的部分只是在重复分叉判断某元素是否在子集和中。
这里以集合S = {-1, 2, 7, 10},目标值t = -1 为例: