【问题标题】:Java Algorithm for All subsets of an array(having integer numbers) satisfying the sum? [closed]满足总和的数组(具有整数)的所有子集的Java算法? [关闭]
【发布时间】:2017-02-10 18:05:12
【问题描述】:

我正在研究 java 程序,它为您提供了对给定总和有贡献的数组的所有可能集合数。

例如 we have an Array of numbers {1,2,2,3,4,5} these might be unsorted

总和“5”的可能子集/输出是{1,2,2} {3,2} {4,1} & {5}

我写的解决方案没有达到目的,请有人在这里帮忙并指出算法中的错误或有其他更好的解决方案。

提前致谢。

代码如下:

public static List<List<Integer>> possibleCombinations(int[] array,
    int requiredSum) {
Arrays.sort(array);
List<List<Integer>> result = new ArrayList<List<Integer>>();
HashSet<String> hello = new HashSet<String>();
for (int i = 0; i < array.length; i++) {
    if (array[i] > requiredSum) {
        break;
    } else if (array[i] == requiredSum) {
        List<Integer> single = new ArrayList<Integer>();
        single.add(requiredSum);
        result.add(single);
        return result;
    }
    for (int j = i + 1; j < array.length; j++) {
        if (array[j] > requiredSum) {
            break;
        } else if (array[j] == requiredSum) {
            List<Integer> single = new ArrayList<Integer>();
            single.add(requiredSum);
            result.add(single);
            return result;
        }
        List<Integer> possibility = new ArrayList<Integer>();
        possibility.add(array[i]);
        int sum = 0;
        sum += array[i];
        for (int k = j; k < array.length; k++) {
            if ((sum + array[k]) < requiredSum) {
                possibility.add(array[k]);
                sum += array[k];
            } else if (sum + array[k] == requiredSum) {
                possibility.add(array[k]);
                result.add(possibility);
                break;
            } else {
                if(possibility.isEmpty() || possibility.size()==1){
                    break;
                }
                sum -= possibility.get(possibility.size() - 1);
                possibility.remove(possibility.size() - 1);
                k--;
                continue;
            }
        }

    }
}

return result;

}

【问题讨论】:

  • 这不是本网站的运作方式。
  • 我们不是来做你的工作并听从你的命令的。
  • 我知道一个具有多项式运行时的!
  • @RamPrakash 我正在寻求帮助,而不是指挥任何人,请参阅我迄今为止尝试过的以下解决方案。
  • @ChrisGong 请找到我到目前为止一直在编写的代码,但并非在所有情况下都有效。

标签: java algorithm data-structures tree


【解决方案1】:

希望对你有帮助。 我没有编译代码,但我很确定它会起作用。

它的复杂度为 O(2^N),其中 N 是元素的数量。

void printSubsetSum(int []nums,int targetSum) {
    int n = nums.length;

    // generate all possible combination from binary representation
    for(int mask=(1<<n)-1;mask>0;mask--) {
        List<Integer> list = new ArrayList<Integer>();

        // check by bit operation
        for(int i=0;i<n;i++) {
            // if ith bit is on then we add our candidate number
            if((mask & (1<<i))!=0) list.add(nums[i]);
        }

        // sum all element in list
        int sum = 0;
        for(int x:list) sum += x;

        // if the sum equals targetSum then we print our list
        if(sum==targetSum) System.out.println(list);
    }
}

我的解决方案如何工作

假设我们有测试输入 {1,2,2,3,4,5}

有 6 个数字,我们想找到 sum = 5 的每个组合。

我的解决方案是生成从 (2^6 - 1) 到 1 的二进制数。

63 = 111111
62 = 111110
61 = 111101
..
3  = 000011
2  = 000010
1  = 000001

对于二进制数位置中的每一个 1,我从 testinput 中选择一个值并将其相加。

例子:

101101 from {1,2,2,3,4,5} that means 1 + 2 + 3 + 5.
000101 from {1,2,2,3,4,5} that means 3 + 5.

【讨论】:

  • 效果很好,感谢您的解决方案
  • @algojava 你能解释一下这个解决方案是如何工作的吗?
  • @hemant:当然,我会编辑我的答案
  • @algojava 。我明白了,感谢您的解决方案。是否有另一种方法可以像 DP 一样降低多项式复杂度。
  • @hemant:在这种情况下,我们想要打印每个组合。所以 2^n 解决方案是最好的。如果我们只想找到 1 个有效的解决方案,那么我们可以使用复杂度 O(n * sum) 的 DP。
【解决方案2】:

我在下面写了算法,但并非在所有情况下都有效,它只打印子集的后续排列。

public static List<List<Integer>> possibleCombinations(int[] array,
        int requiredSum) {
    Arrays.sort(array);
    List<List<Integer>> result = new ArrayList<List<Integer>>();
    HashSet<String> hello = new HashSet<String>();
    for (int i = 0; i < array.length; i++) {
        if (array[i] > requiredSum) {
            break;
        } else if (array[i] == requiredSum) {
            List<Integer> single = new ArrayList<Integer>();
            single.add(requiredSum);
            result.add(single);
            return result;
        }
        for (int j = i + 1; j < array.length; j++) {
            if (array[j] > requiredSum) {
                break;
            } else if (array[j] == requiredSum) {
                List<Integer> single = new ArrayList<Integer>();
                single.add(requiredSum);
                result.add(single);
                return result;
            }
            List<Integer> possibility = new ArrayList<Integer>();
            possibility.add(array[i]);
            int sum = 0;
            sum += array[i];
            for (int k = j; k < array.length; k++) {
                if ((sum + array[k]) < requiredSum) {
                    possibility.add(array[k]);
                    sum += array[k];
                } else if (sum + array[k] == requiredSum) {
                    possibility.add(array[k]);
                    result.add(possibility);
                    break;
                } else {
                    if(possibility.isEmpty() || possibility.size()==1){
                        break;
                    }
                    sum -= possibility.get(possibility.size() - 1);
                    possibility.remove(possibility.size() - 1);
                    k--;
                    continue;
                }
            }

        }
    }

    return result;
}

【讨论】:

  • 你能解释一下它是如何工作的吗?
  • @hemant 它以 O(n3) 的复杂度运行,并且不会在所有情况下运行,algojava 建议的解决方案更好
猜你喜欢
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 2020-12-25
相关资源
最近更新 更多