Recursion - Combination with in array with no repe

2019-07-14 18:17发布

问题:

So I know how to get the size of a combination - factorial of the size of the array (in my case) over the size of the subset of that array wanted. The issue I'm having is getting the combinations. I've read through most of the questions so far here on stackoverflow and have come up with nothing. I think the issue I'm finding is that I want to add together the elements in the combitorial subsets created. All together this should be done recursively

So to clarify:

int[] array = {1,2,3,4,5};

the subset would be the size of say 2 and combinations would be

{1,2},{1,3},{1,4},{1,5},{2,3},{2,4},{2,5},{3,4},{3,5},{4,5}

from this data I want to see if the subset say... equals 6, then the answers would be: {1,5} and {2,4} leaving me with an array of {1,5,2,4}

so far I have this:

 public static int[] subset(int[] array, int n, int sum){
     // n = size of subsets
     // sum = what the sum of the ints in the subsets should be 

    int count = 0; // used to count values in array later
    int[] temp = new temp[array.length]; // will be array returned

    if(array.length < n){
        return false;
    }

    for (int i = 1; i < array.length; i++) {
        for (int j = 0; j < n; j++) {
            int[] subset = new int[n];
            System.arraycopy(array, 1, temp, 0, array.length - 1); // should be array moved forward to get new combinations

                           **// unable to figure how how to compute subsets of the size using recursion so far have something along these lines**
                            subset[i] = array[i];
                            subset[i+1] = array[i+1];

                            for (int k = 0; k < n; k++ ) {
                               count += subset[k];
                            }
                           **end of what I had **

            if (j == n && count == sum) {
                temp[i] = array[i];
                                    temp[i+1] = array[i+1];
            }
        }
    } subset(temp, n, goal);

    return temp;
}

How should I go about computing the possible combinations of subsets available?

回答1:

I hope you will love me. Only thing you have to do is to merge results in one array, but it checks all possibilities (try to run the program and look at output) :) :

public static void main(String[] args) {
    int[] array = {1, 2, 3, 4, 5};
    int n = 2;
    subset(array, n, 6, 0, new int[n], 0);
}

public static int[] subset(int[] array, int n, int sum, int count, int[] subarray, int pos) {
    subarray[count] = array[pos];
    count++;

    //If I have enough numbers in my subarray, I can check, if it is equal to my sum
    if (count == n) {
        //If it is equal, I found subarray I was looking for
        if (addArrayInt(subarray) == sum) {
            return subarray;
        } else {
            return null;
        }
    }

    for (int i = pos + 1; i < array.length; i++) {
        int[] res = subset(array, n, sum, count, subarray.clone(), i);
        if (res != null) {
            //Good result returned, so I print it, here you should merge it
            System.out.println(Arrays.toString(res));
        }
    }

    if ((count == 1) && (pos < array.length - 1)) {
        subset(array, n, sum, 0, new int[n], pos + 1);
    }

    //Here you should return your merged result, if you find any or null, if you do not
    return null;
}

public static int addArrayInt(int[] array) {
    int res = 0;
    for (int i = 0; i < array.length; i++) {
        res += array[i];
    }
    return res;
}


回答2:

You should think about how this problem would be done with loops.

for (int i = 0; i < array.length - 1; i++) {
    for (int j = i + 1; j < array.length; j++) {
        if (array[i] + array[j] == sum) {
            //Add the values to the array
        }
    }
}

Simply convert this to a recursive code.

The best way I can think to do this would be to have each recursive call run on a subset of the original array. Note that you don't need to create a new array to do this as you are doing in your code example. Just have a reference in each call to the new index in the array. So your constructor might look like this:

public static int[] subset(int[] array, int ind, int sum)

where array is the array, ind is the new starting index and sum is the sum you are trying to find