【算法实践】回溯算法——子集求和问题

回溯算法——子集求和问题

给定一个非负整数集合S,找出所有元素和等于给定值SUM的子集。

例如: 

输入: set[] = {1,2,1}, sum = 3
输出: [1,2],[2,1]
解释: 子集 [1,2],[2,1] 的元素和都等于 3.

输入: set[] = {3, 34, 4, 12, 5, 2}, sum = 30
输出: []
解释: 没有任何子集的元素和等于 30.

    1. 分析

子集和问题可视为0-1背包问题的特例。对于每个元素,存在两种处理方式:

  1. 纳入当前元素
    将当前元素纳入子集,随后对剩余元素及更新后的目标值(当前目标值减去元素值)进行递归处理
  2. 排除当前元素
    跳过当前元素,直接对剩余元素及原目标值进行递归处理

当目标值归零时,输出当前子集元素集合。递归终止条件为:

  • 元素遍历完毕
  • 目标值变为负数

此时直接结束当前递归分支。以3个元素集合[1,2,3],SUM=3为例

【算法实践】回溯算法——子集求和问题_第1张图片

    1. C++代码

#include 
using namespace std;


// 若存在子集使得元素和为给定值,则打印所有符合条件的子集
bool flag = 0; // 标记是否存在有效子集
void PrintSubsetSum(int i, int n, int set[], int targetSum,

                                   vector& subset)

{

       // 当目标和降为0时,找到有效子集
       if (targetSum == 0) {
              // 打印当前有效子集
              flag = 1;
 

你可能感兴趣的:(算法实践,算法,回溯,面试)