Given a set of n integers, return all subsets of k elements that add up to 0

given an unsorted set of integers n, return all subsets of size k (i.e. each set has k unique elements) that add up to 0.

So I gave the interviewer the following solution (which I learned at GeekViewpoint ). No extra space is used, everything is done on site, etc. But, of course, cost is the high time complexity of O (n ^ k), where k=tuplein the solution.

public void zeroSumTripplets(int[] A, int tuple, int sum) {
  int[] index = new int[tuple];
  for (int i = 0; i < tuple; i++)
    index[i] = i;
  int total = combinationSize(A.length, tuple);
  for (int i = 0; i < total; i++) {
    if (0 != i)
      nextCombination(index, A.length, tuple);
    printMatch(A, Arrays.copyOf(index, tuple), sum);
  }// for
}// zeroSumTripplets(int[], int, int)

private void printMatch(int[] A, int[] ndx, int sum) {
  int calc = 0;
  for (int i = 0; i < ndx.length; i++)
    calc += A[ndx[i]];
  if (calc == sum) {
    Integer[] t = new Integer[ndx.length];
    for (int i = 0; i < ndx.length; i++)
      t[i] = A[ndx[i]];
    System.out.println(Arrays.toString(t));
  }// if
}// printMatch(int[], int[], int)

But then she imposed the following requirements:

  • should use hashmap in response to reduce time complexity
  • It must be absolutely - ABSOLUTELY - to provide temporary complexity for the general case
  • when k = 6, O (n ^ 3)

, - .

- , ?


EDIT:

, , , k=2.

2 (.. k=2), : . sum - input[i] where i is the index from 0 to n-1, . , , k .

+5
3

, . , , .

subsetsWithSum(A, k, s), k- A, s. :

  • WithSum (x 1... x n, k, s) , WithSum (x 2... x n, k, s) ( ), x 1;
  • , x i, , WithSum (A - x i, k-1, sx i) x i ( ).

, k 1, WithSum (A, 1, s) , s.

,

/**
 * Return all k-length subsets of A starting at offset o that sum to s.
 * @param A - an unordered list of integers.
 * @param k - the length of the subsets to find.
 * @param s - the sum of the subsets to find.
 * @param o - the offset in A at which to search.
 * @return A list of k-length subsets of A that sum to s.
 */
public static List<List<Integer>> subsetsWithSum(
        List<Integer> A,
        int k,
        int s,
        int o)
{
    List<List<Integer>> results = new LinkedList<List<Integer>>();

    if (k == 1)
    {
        if (A.get(o) == s)
            results.add(Arrays.asList(o));
    }
    else
    {
        for (List<Integer> sub : subsetsWithSum(A, k-1, s-A.get(o), o+1))
        {
            List<Integer> newSub = new LinkedList<Integer>(sub);
            newSub.add(0, o);
            results.add(0, newSub);
        }
    }

    if (o < A.size() - k)
        results.addAll(subsetsWithSum(A, k, s, o+1));

    return results;
}

, WithSum (...) , . , subsetsWithSum memoized.

memoize k, s o , , ( ):

public static List<List<Integer>> subsetsWithSum(
        List<Integer> A,
        List<Integer> args,
        Map<List<Integer>, List<List<Integer>>> cache)
{
    if (cache.containsKey(args))
        return cache.get(args);

    int k = args.get(0), s = args.get(1), o = args.get(2);
    List<List<Integer>> results = new LinkedList<List<Integer>>();

    if (k == 1)
    {
        if (A.get(o) == s)
            results.add(Arrays.asList(o));
    }
    else
    {
        List<Integer> newArgs = Arrays.asList(k-1, s-A.get(o), o+1);

        for (List<Integer> sub : subsetsWithSum(A, newArgs, cache))
        {
            List<Integer> newSub = new LinkedList<Integer>(sub);
            newSub.add(0, o);
            results.add(0, newSub);
        }
    }

    if (o < A.size() - k)
        results.addAll(subsetsWithSum(A, Arrays.asList(k, s, o+1), cache));

    cache.put(args, results);
    return results;
}

subsetsWithSum k-, , :

public static List<List<Integer>> subsetsWithZeroSum(List<Integer> A, int k)
{
    Map<List<Integer>, List<List<Integer>>> cache =
            new HashMap<List<Integer>, List<List<Integer>>> ();
    return subsetsWithSum(A, Arrays.asList(k, 0, 0), cache);
}

, (: ) , , , - , .

: , . , , , . , NP-complete, , . .

, :

public static void main(String[] args) {
    List<Integer> data = Arrays.asList(9, 1, -3, -7, 5, -11);

    for (List<Integer> sub : subsetsWithZeroSum(data, 4))
    {
        for (int i : sub)
        {
            System.out.print(data.get(i));
            System.out.print(" ");
        }

        System.out.println();
    }
}

:

9 -3 5 -11
9 1 -3 -7
+4

, , , , , k k/2. k ( O(n^k), , k ), , k/2, - .

k/2 ( S) - , -S. , k/2 k, .

k=6, , 3 ( O(n^3)). - O(1) , O(n^3). O(n^(k/2)), k , k, floor(k/2) floor(k/2)+1.

+3

@kasavbere -

++ Google. .

- , :

+2

All Articles