求一个整数数组w中和为m的所有子集

以整数数组w{11,12,12,13},和m为24为例,所有可能的组合如下图二叉树所示(每层节点关键值相同),其中0代表不选,1代表入选。


image.png

为保存所有可能存在的子集,在遍历二叉树的过程中,我们需要一个解向量保存节点的选用情况,同时遍历的终点为w的长度length。
程序如下:

    //w数组
    static int[] w = {12,31,1,10,46,9,9,8,40,6,-1};
    //w数组长度
    static int n = w.length;
    //条件和
    static int m = 54;
    //解的个数
    static int count = 0;
    //解向量
    static int[] x = new int[n];
    public static void main(String[] args) {
        dfs(0);
    }

    private static void dfs(int i) {
        if(i==n){//遍历终点
            return;
        }
        x[i] = 1;
        dfs(i+1);
        if(calculate(x)==m) printSolution(x);
        x[i] = 0;
        dfs(i+1);
    }

    /**
     * 判断解是否满足条件和
     * @param x
     * @return
     */
    private static int calculate(int[] x) {
        int sum=0;
        for(int i=0;i

可以看出,遍历方式类似二叉树的深度优先遍历,因为深度优先遍历先遍历左节点,再遍历右节点,对应本题先选择节点,再不选节点,也叫回溯算法。
值得注意的是x[i]=1必须写在前面,即置为左节点位置。因为最后一次全不选的情况不会被计算。

你可能感兴趣的:(求一个整数数组w中和为m的所有子集)