Recursive function finding max value - java

I feel like I am pretty close, but my return value keeps printing out the first value in the array..
public static double mx(int[] nums, int track)
maxNow = nums[0];
if (count < [lengthofarray] - 1 && nums[track] != 0)
{
if (numbers[track] > maxval)
maxval = numbers[track];
System.out.println(maxval);
return maxval = mx(nums, track+1);
}
else
return maxval;
}

currentMax is a local variable declared inside findMax. This means that if findMax calls itself, which calls itself again, which calls itself again, so that it's now on the stack four times, there will be four different currentMax variables; each findMax has its own. Thus, if one of those findMax invocations modifies currentMax, it only modifies its own; the modification has no effect on the local currentMax variables belonging to the other invocations of findMax.
There are ways to get the method invocations to share the same currentMax (passing it as a parameter, as suggested in another answer, is a possibility), but you don't need them here. Instead, look at the problem a little differently: If you want to find the maximum of numbers[3] through numbers[10], you can call your function recursively to find the maximum of numbers[4] through numbers[10], then look at numbers[3] and compare it against the maximum you found recursively.
P.S. I do not recommend making currentMax a static field in order to get it to be shared; using a global field to hold results of recursion is usually poor programming practice, in my view. (It introduces thread-unsafety, for one thing.) There are ways to do this if done carefully, but in general I believe it should be avoided.

try to simplify the code:
public static int findMax(int[] numbers, int count){
if (count > 0) {
return Math.max(numbers[count], findMax(numbers, count-1))
}
else {
return numbers[0];
}
}

Here is how you can visualize this problem:
Your data can look like
{a, b, c, d, e}
you need to find max using
max(a, max(restOfElements))
which means you need to again use
max(a, max(b, max(restOfElements)))
.
.
.
max(a, max(b, max(c, max (d, max(e, nothing)))))
and last case can be visualized even better as
max(a, . . . . )
max(b, . . . )
max(c, . . )
max (d, . )
max(e, nothing)
So in the end you have two cases
when you are handling e, where you can't compare it with anything
when you are comparing current value with max of values after it
To handle first case you just need to return e because there is nothing else to compare it with.
To handle second case just get max value from rest of elements, compare it with your current value and return greater one.
Here is how your code can look like (hover over box to see code, but before you do it, try to implement it yourself again)
public static double findMax(double[] numbers, int count) {
if (count == numbers.length - 1)//we are handling last element
return numbers[count];
//else, we are returning greater number between current element,
//and max from rest of elements
return Math.max(numbers[count], findMax(numbers, count + 1));
}
Usage example:
double[] arr = { 1, 2, 2, 1, 4, 3 };
System.out.println(findMax(arr, 0));
Output: 4.0
As an exercise instead of dividing your problem inmax(a, max(b, max(c, max(d, max(e)))) try to create method which will do it like max(max(max(max(max(a), b), c), d), e)

Well since we're giving out answers, here's how I would do it:
max(arr[1-n]) = max(arr[1], max(arr[2-n]);
public static double findMax(final double ...arr){
return findMax(arr, 0);
}
private static double findMax(final double[] arr, final int start){
// base case, if this is the end of the array, the max of the "rest"
// is just this element
if(start == arr.length - 1)
return arr[start];
// else continue
// find the max of the rest of the array
final double nextMax = findMax(arr, start + 1);
// return this index if it's greater than the next max,
// else return the next max
return arr[start] > nextMax ? arr[start] : nextMax;
}

Here's my try at it:
public static double findMax(double[] numbers, int count, double currentMax){
if( count < numbers.length ){
if( numbers[count] > currentMax ){
currentMax = numbers[count];
}
currentMax = findMax( numbers, count+1, currentMax );
}
return currentMax;
}

What exactly is the purpose of && numbers[count] != 0? What if all your numbers are negative?
Second, try passing the currentmax as an argument, instead of initializing it inside the method. You want to keep track of your currentMax. Initializing it as a local variable would not do that, but would reset it to the first element at each call.
public static double findMax(double[] numbers, int count, double currentMax)
{
if (count < numbers.length)// && numbers[count] != 0) //While the value of count remains lower than the size of the array and the current element of the arraylist doesn't = 0, the execute the code..
{
if (numbers[count] > currentMax)
currentMax = numbers[count];
return currentMax = findMax(numbers, count+1, currentMax);
}
else return currentMax;
}

Related

How can I find the largest subarray sum if all the elements are negative and I have set the maxSum to 0, which is used to compare other elements?

Can someone help me with this. My code is working fine but consider a case of [-2,-1]. Since my maxSum is set to 0. My output is coming 0 instead of-1. How should I modify my code?
Sample i/o:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
class Solution {
public int maxSubArray(int[] nums) {
int sum=0,maxSum=0, i=0;
if(nums.length==1) return nums[0];
for( i=0;i<nums.length-1;i++){``
sum+=nums[i];
for(int j=i+1;j<nums.length;j++){
sum+=nums[j];
if(sum>maxSum){
maxSum=sum;
}
}
sum=0;
}
return (nums[i]>maxSum)?nums[i]:maxSum;
}
}
Whenever the sum<maxSum I'm not touching the maxSum but when all the elements are negative sum<maxSum will always be true and I'm getting returned 0, rather I should get the maximum negative number. I don't want to change my approach can I get it right by some slight modifications?
Here you can do this:
class Solution {
public int maxSubArray(int[] nums) {
int sum=0,maxSum=0, i=0,negativeMaxSum=Integer.MIN_VALUE; //change here
if(nums.length==1) return nums[0];
for( i=0;i<nums.length-1;i++){
sum+=nums[i];
negativeMaxSum = (nums[i]<0 && nums[i]>negativeMaxSum) ? nums[i]: negativeMaxSum; //change here
negativeMaxSum = (nums[i]==0) ? 0: negativeMaxSum; //change here (if there exist a 0 in the array then we don't need to show the greatest negative integer)
for(int j=i+1;j<nums.length;j++){
sum+=nums[j];
if(sum>maxSum){
maxSum=sum;
}
}
sum=0;
}
maxSum= (maxSum == 0 && negativeMaxSum>Integer.MIN_VALUE) ? negativeMaxSum: maxSum; //change here
return (nums[i]>maxSum)?nums[i]:maxSum;
}
You can create a new variable negativeMaxSum and compare it with each element, eventually negativeMaxSum will always store the maximum negative element and we will check if our maxSum is 0 and negativeMaxSum > least value for an integer(it means that there exist a negative integer) and we also checked if there existed a zero and if it did then we assigned it to our negativeMaxSum.

Sum Array if a condition is met

I want to sum (running sum) the values of an int Array and put the result in new array on corresponding position. If sum <0, result should be 0.
I'm trying to find a better way to write below code? Maybe with streams java8?
int[] originalArray = {3,7,-12,1,8,5};
int[] resultArray= new int[originalArray.length];
resultArray[0]=(originalArray[0]<0) ? 0:originalArray[0];
for(int i=1;i<originalArray.length;i++){
int sum=resultArray[i-1]+originalArray[i];
resultArray[i]=(sum<0) ? 0 : sum;
// System.out.println(resultArray[i]);
}
You don't need streams for this, a simple loop like you've already used is enough:
for (int i = 0, previous = 0; i < originalArray.length; i++) {
previous = resultArray[i] = Math.max(originalArray[i] + previous, 0);
}
You see that I introduced two things:
previous: a helper variable, which tracks the previous result
Math.max(): a useful method, it allows us to pick the result if it is positive or else 0 when it is negative (0 is greater than any negative)
The method looks something like this, which is exactly what you've done already:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
If you don't like the multiple assignment line:
previous = resultArray[i] = Math.max(originalArray[i] + previous, 0);
Then you could also write it like this, if that's more understandable:
previous = Math.max(originalArray[i] + previous, 0);
resultArray[i] = previous;

How to find the maximum value in a linked list recursively?

I need to find the maximum value in a linked list given the head of the list as a parameter recursively. I have no clue how to start the recursive part of the method. This is all I have so far.
int maxOfList(List M){
List max = M;
if(M == null)
return max;
if(M.next > max){
max = M.restOfTheInts;
return maxOfList();
}
}
In recursion, you often need an entry method and a worker method. The entry method is the special case that allows the worker method to work in all cases, and the worker does the recursion.
For example, your worker might be something like:
int maxOfList(int currentMax, List<int> listToCheck) {
// Nothing to compare? currentMax is it!
if (listToCheck == null || listToCheck.size() == 0) return currentMax;
// Compare and return.
List<int> restOfList = listToCheck.subList(1, listToCheck.size());
return maxOfList(Math.max(currentMax, listToCheck.get(0)), restOfList);
}
And then to kick that off, you need your entry method:
int maxOfList(List<int> listToCheck) {
return maxOfList(Integer.MIN_VALUE, listToCheck);
}
So, for recursion to effectively work, you need to have the whole context visible inside the function.
int maxOfList(List m) {
if(m.next == null)
return m;
int previousMax = maxOfList(m.next);
if(m > previousMax)
return m;
else
return previousMax;
}
int maxValue(List m){
return maxValue(m, Integer.MIN_VALUE);
}
int maxValue(List m, int num){
if(m.next == null){
if(m.data > num)
return num = m.data;
}
return maxValue(m.next, num);
}
This should be pretty straightforward. In order to achieve a recursive solution, think about all these steps:
What's the recursive idea? The maximum of a list {L} is the max(Li, {L} - Li), where Li is the current element;
What's the stop condition? We know that if a list is empty, the maximum could be something that any number will be greater, let's say MIN_INT;
Putting all together: So, at the end we could say that a pseudo-code would look like this:
int maxOfList(List M) {
if(M == null)
return Integer.MIN_VALUE;
int max = maxOfList(M.next);
return M.value > max ? M.value : max;
}
I am supposing that the linked list has its content in value and points to next element in next (tail pointing to null). If you find any further problems, take a look at this posts:
Finding Max value in an array using recursion
Python: Recursive function to find the largest number in the list

How to find the location of the largest element in an array using recursion?

Given an array list, and the count of element on the list find the location of the largest element using recursion.
So far, I'm able to find the largest element, but I need the location of that element on the array and not the actual value.
private int getLargestElementLoca(int[] list, int count)
{
int largestValue;
if(count == 1){
return 0;
}
int tempMax = getLargestElementLoca(list,count-1);
largestValue = Math.max(list[count-1],tempMax);
return largestValue;
}
You're on the right track, but you just need some tweaks. I'm not going to write the code for you, but here are some clues.
If you want your function to return the index instead of the maximum value, then you need to change the way you compute the return value and the way you use it recursively.
private int getLargestElementLoca(int[] list, int count)
{
int largestValue;
if(count == 1){
return 0;
}
If there is only one element to look at, i.e. list[0], then list[0] will be the maximum, and 0 will be its index. So returning 0 is correct here.
int tempMax = getLargestElementLoca(list,count-1);
You've redefined getLargestElementLoca so that it returns an index, not a maximum value. That applies to your recursive call also, so tempMax is going to be an index and not a value. That means that you can't pass it directly into Math.max. Some adjustment will be necessary, but keep reading.
largestValue = Math.max(list[count-1],tempMax);
Math.max returns the largest value, but that isn't what you want. You have two indexes, count-1 and something else, and you want to compute the index of the larger value. You can't do that with Math.max, but you can use an if statement or the conditional operator a ? b : c. It would also be helpful to rename the variable, since it's no longer going to contain the largest value.
An idea could be to split your array recursiv into two parts until there are only 2 or 1 elements remainning. Finding the max value in two numbers or one is simple und return it. Then you compare the two returned values and return the max.
Recursion is simple, but you should know about doing it iteratively:
private int getMaxLocation(int[] array) {
int maxpos = 0;
int max = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
maxpos = i;
}
}
return maxpos;
}
If you were to do this through recursion, you would need to track a few variables across it:
private int getMaxLocation(int[] array, int pos, int max, int maxpos) {
if (pos >= array.length || pos < 0) {
return maxpos;
} else {
int current = array[pos];
if (current > max) {
max = current;
maxpos = pos;
}
return getMaxLocation(array, ++pos, max, maxpos);
}
}
//calling this
int max = getMaxLocation(yourArray, 0, Integer.MIN_VALUE, 0);

Finding the minimum of an array using recursion?

Ok, so I've been trying to wrap my head around recursion in Java and I can accomplish easy tasks such as sum, reversing etc. but I have been struggling to do this exercise:
I'm trying to find the minimum number in an array using recursion but keep getting an answer of 0.0.
My understanding for recursion is that there I need to increment one element and then provide a base case that will end the recursion. I think I'm messing up when I have to return a value and when is best to call the recursion method.
This is what I have so far:
public static double findMin(double[] numbers, int startIndex, int endIndex) {
double min;
int currentIndex = startIndex++;
if (startIndex == endIndex)
return numbers[startIndex];
else {
min = numbers[startIndex];
if (min > numbers[currentIndex]) {
min = numbers[currentIndex];
findMin(numbers, currentIndex, endIndex);
}
return min;
}
} //findMin
Here's a simplified version:
public static double min(double[] elements, int index) {
if (index == elements.length - 1) {
return elements[index];
}
double val = min(elements, index + 1);
if (elements[index] < val)
return elements[index];
else
return val;
}
Hint: You're calling findMin recursively, but then not using its return value.
What's the relationship between (1) the min of the whole array, (2) the first element, and (3) the min of everything apart from the first element?
There are a variety of problems in this code including:
You don't use the result of the recursive findMin call.
startIndex will be the same for every call to findMin, because currentIndex is being set to the value of startIndex before startIndex is incremented.
If the number at index 1 in the array is <= the number at index 0, you just return that number without even making the recursive call.
A few observations in addition to the first answer:
int currentIndex = startIndex++; - you're going to miss your first element here. In general, you don't want to modify the input to your recursive function. Work off the input and generate new values when you're ready to call the function again - i.e. 'findMin(numbers, currentIndex+1, endIndex)'

Categories