1

This is what I have so far, but I'm confused on how to keep track of the index. I would change the parameters of the method, but I'm not allowed. I can only use a loop to make another array. Those are the restrictions.

public class RecursiveFinder {

    static int checkedIndex = 0;
    static int largest = 0;


    public static int largestElement(int[] start){
        int length = start.length;

        if(start[length-1] > largest){
            largest = start[length-1];
            int[] newArray = Arrays.copyOf(start, length-1);
            largestElement(newArray);
        }
        else{
            return largest;
        }
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        int[] array1 = {0,3,3643,25,252,25232,3534,25,25235,2523,2426548,765836,7475,35,547,636,367,364,355,2,5,5,5,535};
        System.out.println(largestElement(array1));
        int[] array2 = {1,2,3,4,5,6,7,8,9};
        System.out.println(largestElement(array2));
    }

}
8
  • 1
    so, should largestElement return the index or the value of the max element? Commented Nov 22, 2016 at 21:32
  • You can keep a counter value to keep track of your index. Commented Nov 22, 2016 at 21:34
  • 2
    What is the original problem? Are you sure you need to solve the problem with copying? Commented Nov 22, 2016 at 21:35
  • Can you post more details about the restrictions of the problem involving recursion? Using recursion in this way making a copy each time is very inefficient. But the way you are using it would mean index is the length of the array. Commented Nov 22, 2016 at 21:37
  • 1
    You can't change the method's number of parameters. However can you create one more method to be used within the required one? Commented Nov 22, 2016 at 22:02

8 Answers 8

1

Recursive method doesn't need to keep the largest value inside.

2 parameters method

Start to call with:

largestElement(array, array.length-1)

Here is the method:

public static int largestElement(int[] start, int index) {
    if (index>0) {
        return Math.max(start[index], largestElement(start, index-1))
    } else {
        return start[0];
    }
}

The 3rd line of method is the hardest one to understand. It returns one of two elements, larges of the one of current index and of remaining elements to be checked recursively.

The condition if (index>0) is similar to while-loop. The function is called as long as the index remains positive (reaches elements in the array).


1 parameter method

This one is a bit tricky, because you have to pass the smaller array than in the previous iteration.

public static int largestElement(int[] start) {
    if (start.length == 1) {
        return start[0];
    }
    int max = largestElement(Arrays.copyOfRange(start, 1, start.length));
    return start[0] > max ? start[0] : max;
}

I hope you do this for the study purposes, actually noone has a need do this in Java.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure if you read the question. OP says the arguments to the method can't change.
Oh, you are right. I admit I checked the body containing code mostly.
Thank you, Nikolas. Yea, and trust me, I know how futile the use of recursion is in this situation with these restrictions.
0

Try that for the upper class, leave the main method it's is correct.

public class dammm {



public static int largestElement(int[] start){
int largest = start[0];

for(int i = 0; i<start.length; i++) {
    if(start[i] > largest){

        largest = start[i];
    }

    }return largest;
}

2 Comments

I'm not sure if you read the question. OP say must use recursion and for loop only to copy the array.
Needs to use recursion
0

If your goal is to achieve this by using recursion, this is the code that you need. It is not the most efficient and it is not the best way to deal with the problem but it is probably what you need.

public static int largestElement(int[] start){
    int length = start.length;

    if (start.lenght == 1){
        return start[0];
    } else {
        int x = largestElement(Arrays.copyOf(start, length-1))
        if (x > start[length-1]){
            return x;
        } else {
            return start[length-1];
        }
    }       
}

Imagine that you have a set of numbers you just have to compare one number with the rest of them.

For example, given the set {1,8,5} we just have to check if 5 is larger than the largest of {1,8}. In the same way you have to check if 8 is larger than the largest of {1}. In the next iteration, when the set one have one value, you know that that value is the bigger of the set.

So, you go back to the previous level and check if the returned value (1) is larger than 8. The result (8) is returned to the previous level and is checked against 5. The conclusion is that 8 is the larger value

Comments

0

One parameter, no copying. Tricky thing is, we need to pass a smaller array to the same method. So a global variable is required.

    // Number of elements checked so far.
    private static int current = -1;

    // returns the largest element.
    // current should be -1 when user calls this method.
    public static int largestElement(int[] array) {
        if (array.length > 0) {
            boolean resetCurrent = false;

            if (current == -1) {
                // Initialization
                current = 0;
                resetCurrent = true;
            } else if (current >= array.length - 1) {
                // Base case
                return array[array.length - 1];
            }

            try {
                int i = current++;
                return Math.max(array[i], largestElement(array));
            } finally {
                if (resetCurrent) {
                    current = -1;
                }
            }
        }
        throw new IllegalArgumentException("Input array is empty.");
    }

If you can create another method, everything would be much simpler.

private static int recursiveFindLargest(int [] array, int i) {
    if (i > 0) {
        return Math.max(array[i], recursiveFindLargest(array, i-1));
    } else {
        return array[0];
    }
}

public static int largestElement(int [] array) {
    // For empty array, we cannot return a value to indicate this situation,
    //all integer values are possible for non-empty arrays.
    if (array.length == 0) throw new IllegalArgumentException();

    return recursiveFindLargest(array, array.length - 1);
}

Comments

0

For this problem you really need to think about working with the base case. Take a look at some of the simple cases you would have to deal with:

  1. If the array is length 1, then you return the only value
  2. If the array is length 2, then you return the maximum of the two values
  3. If the array is length 3, then ?

From the above we can get an idea of the structure of the problem:

if array.length == 1 then
    return array[0]
else
    return the maximum of the values

In the above if we have only one element, it is the maximum value in the list. If we have two values, then we have to find the maximum of those values. From this, we can then use the idea that if we have three values, we can find the maximum of two of them, then compare the maximum with the third value. Expanding this into pseudo code, we can get something like:

if array.length == 1 then
    return array[0]
else
    new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
    return maximum(array[0], largestElement(new array))

To explain the above a little better, think of execution like a chain (example for {1, 2, 3}).

  • Array: {1, 2, 3}, maximum(array[0] = 1, largestElement(new array = {2, 3}))
    • Array: {2, 3}, maximum(array[0] = 2, largestElement(new array = {3}))
      • Array: {3}, array[0] = 3 => length is 1 so return 3

The above then rolls back up the 'tree' structure where we get:

maximum (1, maximum(2, (return 3)))

Once you have the maximum value, you can use the sample principle as above to find the index with a separate method:

indexOf(array, maximum)
    if array[0] == maximum then
       return 0
    else if array.length == 1 then
       return -1 
    else
       new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
       result = indexOf(new array, maximum)
       return (result == -1) ? result : result + 1

For looking into this more, I would read this from the Racket language. In essence it shows the idea of array made purely from pairs and how you can use recursion to do iteration on it.

If you are interested, Racket is a pretty good resource for understanding recursion. You can check out University of Waterloo tutorial on Racket. It can give you a brief introduction to recursion in an easy to understand way, as well as walking you through some examples to understand it better.

Comments

0

You don't need to keep a largest variable outside your method - that's generally not a good practice with recursion which should return all context of the results.

When you think about recursion try to think in terms of a simple base case where the answer is obvious and then, for all other cases how to break it down into a simpler case.

So in pseduo-code your algorithm should be something like:

func largest(int[] array)
    if array has 1 element
        return that element
    else
        return the larger of the first element and the result of calling largest(remaining elements)

You could use Math.max for the 'larger' calculation.

It's unfortunate that you can't change the arguments as it would be easier if you could pass the index to start at or use lists and sublists. But your copying method should work fine (assuming efficiency isn't a concern).

An alternative to the algorithm above is to make an empty array the base case. This has the advantage of coping with empty arrays (by return Integer.MIN_VALUE):

int largest(int[] array) {
    return array.length == 0 
        ? Integer.MIN_VALUE
        : Math.max(array[0], largest(Arrays.copyOfRange(array, 1, array.length)));
}

2 Comments

So how exactly would I use the Math.max. Would I need a helper method? Also, how does this method keep track of the index exactly?
I've added an example that uses Math.max. I'm not sure what you mean about keeping track of index. There's no need to do that.
0

Here is working example of code with one method param

    public int max(int[] list) {
        if (list.length == 2) return Math.max(list[0], list[1]);
        int max = max(Arrays.copyOfRange(list, 1, list.length));
        return list[0] < max ? max : list[0];
    }

Comments

0
private static int maxNumber(int[] arr,int n,int max){
    if(n<0){
        return max;
    }
   max = Math.max(arr[n],max);
   return maxNumber(arr,n-1,max);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.