给定一个数组,找到总和为k的所有子集

时间:2013-08-10 04:09:51

标签: java algorithm set subset

非常简单的问题:

  

给定一个数组,找到所有与k值相加的子集

我试图用Java做这个,似乎找到了一个解决方案,可以在O(n ^ 2)时间内解决它。这个解决方案是正确的O(n ^ 2)实现吗?

      @Test
    public void testFindAllSubsets() {
        int[] array = {4,6,1,6,2,1,7};
        int k=7;
                 // here the algorithm starts
        for(int i = 0; i < array.length;i++){
            // now work backwords
            int sum = array[i];
            List<Integer> subset = new ArrayList<Integer>();
            subset.add(array[i]);
            for(int j = array.length -1; j > i && sum < k; j--){
                int newSum = sum + array[j];
                                    // if the sum is greater, than ditch this subset
                if(newSum <= k){
                    subset.add(array[j]);
                    sum = newSum;
                }
            }
            // we won't always find a subset, but if we do print it out
            if(sum == k){
                System.out.print("{");
                System.out.print(subset.get(0));
                for(int l = 1; l < subset.size(); l++){
                    System.out.print(","+subset.get(l));
                }
                System.out.print("}");
                System.out.println();
            }
        }
    }

我已经尝试了各种各样的例子,并没有找到任何似乎打破它。但是,当我在网上搜索时,这似乎不是问题的常见解决方案,许多解决方案声称这个问题是O(2 ^ n)。

P.S。 这不是一个家庭作业的问题,我是一个试图在Java中使用我的Comp Sci基础的工作的编程人员。谢谢!

2 个答案:

答案 0 :(得分:2)

不,这不正确。举个简单的例子

  

你的数组是4,6,1,2,3,1,目标总和是7然后在你的逻辑中   只会找到(4,3)(6,1)(1,2,3,1)你的代码会遗漏(4,2,1),(4,3)。

我会参考wiki

答案 1 :(得分:1)

一个优雅的解决方案是简单地想到一个子集,因为每个成员回答“我是不是在?”?所以基本上每个人都可以回答是/否,所以你有2个 N 子集(包括空子集)。编写此代码的最自然方式是递归每个元素并执行以下操作之一:

  1. 选择
  2. 跳过它
  3. 因此,时间复杂度为O(2 N ),原因很简单,因为在最坏的情况下你可以得到这么多答案。