简体   繁体   中英

How to work on the same array across the recursion stack (or: How to pass a partial solution to the previous/next recursive call to method)

In a method (that I wrote so far):

private int[] calculateSum(int[] array, int index) {
    int[] result = new int[array.length];
    if (index > 0) { //implicit break condition
        calculateSum(array, index-1);
        result[index] = array[index]+result[index-1]; //should be sum of array values up until array[index]
    }
    return result;
}

I am supposed to populate the new array based on the elements of the argument array, and return the new array.

But, how can I keep returning the partially populated array result to the previous recursive call? When this code runs, a new array result is being created in each recursive call. I can't use helper methods, global variables, or anything except the method as it is defined.

Generally (and most importantly) how do I pass the partial/current solution to the next method call if I can't use accumulator, or any extra variables? If I create a variable inside the method, every subsequent recursive call creates a new variable, the values of which I can't pass to the previous frame.

Another typical example is: count the number of zeroes in a given integer recursively using only the method with the signature:

int noZeroes(int x) {}

All the sources I found incl. R.Sedgewick, ESRoberts, MTGoodrich et al. use different 'helper structures' in the examples, so I can't find any instructions on how to deal with recursion with 'limited' resources.

I'm assuming i and index are supposed to be the same thing here.

What you are missing is using the array returned by calculateSum(array, i-1) .

The idea is to create a single array at the end of the recursion, add to keep modifying that array on each recursive call:

private int[] calculateSum(int[] array, int index) 
{
    if (index == 0) {
        return Arrays.copyOf (array, array.length);
    } else {
        int[] result = calculateSum(array, index-1);
        result[index] += result[index-1];
        return result;
    }
}

When you reach the end of the recursion, you create a copy of the input array. That's the array you return. Then, you modify one element of the array each time a recursive call returns.

For the input:

{1,2,3,4,3}

this method will return:

[1, 3, 6, 10, 13]
  • When index == 0 , you return a copy of the original array: {1,2,3,4,3} .
  • When index == 1 , you add result[0] to result[1] and return: {1,3,3,4,3} .
  • When index == 2 , you add result[1] to result[2] and return: {1,3,6,4,3} .
  • When index == 3 , you add result[2] to result[3] and return: {1,3,6,10,3} .
  • When index == 4 , you add result[3] to result[4] and return: {1,3,6,10,13} .

BTW, if you are allowed to modify the input array, you can change this method to a void method, and the input array will contain the result:

private void calculateSum(int[] array, int index) {
    if (index > 0) {
        calculateSum(array, index-1);
        array[index] += array[index-1];
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM