I have that method valorMaxim([1, 5, 252, 24, 7, 82, 3])
returns 252.
I don't know how to do it. I have been thinking if I could decrease the array length.
public static int valorMaxim(int arr[]){
int max;
if(arr.length==1)
return arr[0];
for (int i = 0; i < arr.length; i ) {
if (arr[i] < arr[i 1]) {
max=arr[i 1];
return arr[i 1];
}
}
return valorMaxim(arr);
//Retorna el valor màxim en un array no buit d’enters.
}
CodePudding user response:
I modified the accepted answer to Finding Max value in an array using recursion.
As you suggested (i.e. decrease the array length with each recursive method invocation), I create a copy of the method parameter whose length is one less than the parameter and remove the first element. Then I recursively call the method with the array copy.
public class Main {
public static int valorMaxim(int arr[]){
if (arr.length == 1) {
return arr[0];
}
else {
int[] tmp = new int[arr.length - 1];
System.arraycopy(arr, 1, tmp, 0, tmp.length);
return Math.max(arr[0], valorMaxim(tmp));
}
}
public static void main(String[] args) {
System.out.println(valorMaxim(new int[]{1, 5, 252, 24, 7, 82, 3}));
}
}
CodePudding user response:
Basically, the recursive idea is:
- If the array has length 1, return the only element;
- Otherwise, split the array into
x
the first element, andxs
the rest; - Find the maximum element within
xs
, compare it tox
and yield the greater.
There are two ways to achieve such a "split":
Create a new copy of part of the array for
xs
You can either use
System.arraycopy
(see answer by @Abra) orArrays.copyOfRange
, which is simpler:int x = arr[0]; int[] xs = Arrays.copyOfRange(arr, 1, arr.length);
And now we lookup the maximum element within
xs
(which isvalorMaxim(xs)
), and compare it tox
as the final result:return Math.max(x, valorMaxim(xs));
Put everything together, and don't forget to add a length checker:
public static int valorMaxim(int arr[]) { if (arr.length == 1) return arr[0]; int x = arr[0]; int[] xs = Arrays.copyOfRange(arr, 1, arr.length); return Math.max(x, valorMaxim(xs)); }
And that's it! Since we have the length checker in the first place, we can safely make sure
xs
would never be empty, and hencevalorMaxim(xs)
would never result inArrayIndexOutOfBoundsException
.Set a boundary for the array
You may have found that copying a new array at each time could be time- and memory-consuming. Instead of creating a physical copy for
xs
, we can conceptualise the idea and use a bounded array instead. We would need to define a helper method to do so:private static int findMaxBound(int arr[], int startFrom) { // does "xs" have length 1? if (startFrom == arr.length - 1) return arr[startFrom]; int x = arr[startFrom]; int maxInXs = findMaxBound(arr, startFrom 1); return Math.max(x, maxInXs); }
And then we can define
valorMaxim
aspublic static int valorMaxim(int arr[]) { return findMaxBound(arr, 0); }
In the end, we did not create any new copies of
arr
but uses different ranges of itself and treat them asxs
throughout the process.