I have a program that I'm trying to make for class that returns the sum of all the integers in an array using recursion. Here is my program thus far:
public class SumOfArray {
private int[] a;
private int n;
private int result;
public int sumOfArray(int[] a) {
this.a = a;
n = a.length;
if (n == 0) // base case
result = 0;
else
result = a[n] + sumOfArray(a[n-1]);
return result;
} // End SumOfArray method
} // End SumOfArray Class
But I'm getting three error which are all related, I believe, but I can't figure out why it is finding a type of null:
SumOfArray.java:25: sumOfArray(int[]) in SumOfArray cannot be applied to (int)
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: operator + cannot be applied to int,sumOfArray
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: incompatible types
found : <nulltype>
required: int
result = a[n] + sumOfArray(a[n-1]);
^
3 errors
The solution is simpler than it looks, try this (assuming an array with non-zero length):
public int sumOfArray(int[] a, int n) {
if (n == 0)
return a[n];
else
return a[n] + sumOfArray(a, n-1);
}
Call it like this:
int[] a = { 1, 2, 3, 4, 5 };
int sum = sumOfArray(a, a.length-1);
The issue is that a[n-1] is an int, whereas sumOfArray expects an array of int.
Hint: you can simplify things by making sumOfArray take the array and the starting (or ending) index.
a[n-1]
is getting the int at n-1, not the array from 0 to n-1.
try using
Arrays.copyOf(a, a.length-1);
instead
How about this recursive solution? You make a smaller sub-array which contains elements from the second to the end. This recursion continues until the array size becomes 1.
import java.util.Arrays;
public class Sum {
public static void main(String[] args){
int[] arr = {1,2,3,4,5};
System.out.println(sum(arr)); // 15
}
public static int sum(int[] array){
if(array.length == 1){
return array[0];
}
int[] subArr = Arrays.copyOfRange(array, 1, array.length);
return array[0] + sum(subArr);
}
}
a is an int array. Thus a[n-1] is an int. You are passing an int to sumOfArray which expects an array and not an int.
Try this if you don't want to pass the length of the array :
private static int sumOfArray(int[] array) {
if (1 == array.length) {
return array[array.length - 1];
}
return array[0] + sumOfArray(Arrays.copyOfRange(array, 1, array.length));
}
Offcourse you need to check if the array is empty or not.
This is the one recursive solution with complexity O(N).and with input parameter A[] only.
You can handle null and empty(0 length) case specifically as Its returning 0 in this solution. You throw Exception as well in this case.
/*
* Complexity is O(N)
*/
public int recursiveSum2(int A[])
{
if(A == null || A.length==0)
{
return 0;
}
else
{
return recursiveSum2Internal(A,A.length-1);
}
}
private int recursiveSum2Internal(int A[],int length)
{
if(length ==0 )
{
return A[length];
}
else
{
return A[length]+recursiveSum2Internal(A, length-1);
}
}
without any predefined function.
public static int sum(int input[]) {
int n = input.length;
if (n == 0) // base case
return 0;
int small[]=new int[n-1];
for(int i=1;i<n;i++)
{
small[i-1]=input[i];
}
return input[0]+sum(small);
}
private static int sum(int[] arr) {
// TODO Auto-generated method stub
int n = arr.length;
if(n==1)
{
return arr[n-1];
}
int ans = arr[0]+sum(Arrays.copyOf(arr, n-1));
return ans;
}
Simplified version:
//acc -> result accumlator, len - current length of array
public static int sum(int[] arr, int len, int acc) {
return len == 0 ? acc : sum(arr, len-1, arr[len-1]+ acc);
}
public static void main(String[] args) {
int[] arr= { 5, 1, 6, 2};
System.out.println(sum(arr, arr.length, 0));
}
Related
Without using a loop, I'm trying to count the number of times a given integer is in an array using recursion. I keep getting a StackOverflow error and I can't figure out why.
public static int countOccurrences(int[] arr, int n) {
if (arr.length == 0) {
return 0;
}
if (arr[0] == n) {
return 1 + countOccurrences(arr, n - 1);
}
return countOccurrences(arr, n - 1);
}
}
If you can use only two parameters, then try:
public static int countOccurrences(int[] arr, int n) {
if (arr.length == 0) {
return 0;
}
if (arr[0] == n) {
return 1 + countOccurrences(Arrays.copyOfRange(arr, 1, arr.length), n);
}
return countOccurrences(Arrays.copyOfRange(arr, 1, arr.length), n);
}
the problem with above code is that the base condition will never be satisfied as you are never trying to reduce the length of the array. To keep track of length traversed, you can use a variable that starts from end to start ( or from start to end your choice ) . And let's say , num is the value that you want to count. Then you can change your code to like this :
public class CountFrequency {
public static void main(String[] args) {
int A[] = { 1, 2, 3, 4, 5, 5 };
int count = countOccurences(A, 5);
System.out.println(count);
}
private static int countOccurences(int[] arr, int num) {
return helper(arr, num, arr.length - 1);
}
private static int helper(int[] arr, int num, int i) {
if (i == -1) {
return 0;
}
if (arr[i] == num)
return 1 + helper(arr, num, i - 1);
else
return helper(arr, num, i - 1);
}
}
and the output is
2
Could someone please help me with the recursion code below?
Given an input array and a target, I want to return a boolean true for any nonempty subset which sums up to the target value. I am confused about how to return the correct boolean value from recursion.
In my approach below, I am summing up all the possible combinations of a non-empty sub-set and want to return True to the calling function if any of the non-empty subsets equals the target value. The issue is, due to the multiple recursive call stacks, the correct/expected value for the boolean for a sub-set gets overwritten by the subsequent/remaining recursive call stacks. Is there a work-around for this issue? Or do I use brute force? where-in I store all the possible boolean values for each sub-set combination in a list and return true if atleast one value in the list is a boolean True?
public class RecursionPossibleToAchieveTargetSum {
public static void main(String[] args ) {
long[] arr = {4,8};
long k = 4;
boolean flag = false;
if (arr.length > 0 )
flag = recursionHelper(arr,0,new long[arr.length],0, k);
System.out.println(flag);
}
public static Boolean recursionHelper(long[] arr, int spos, long[] temp, int tempIndex, long target) {
if ( spos == arr.length ) {
return (recursiveAddition(temp, temp.length - 1) == target);
}
recursionHelper(arr, spos + 1, temp, tempIndex, target );
temp[tempIndex] = arr[spos];
return recursionHelper(arr, spos + 1, temp, tempIndex + 1, target);
}
public static long recursiveAddition(long[] arr, int spos) {
if ( spos == 0 ) {
return arr[spos];
} else {
return arr[spos] + recursiveAddition(arr, spos-1);
}
}
}
You can use a List<long[]> to save all the subsets that add up to the target. I also cleaned up the recursion a bit. You can check the size of this result list with "result.size() > 0" and print that boolean. You can also print each array of subsets to know which ones there are.
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
public class RecursionPossibleToAchieveTargetSum {
public static void main(String[] args ) {
long[] arr = {1,2,4,1,3,5};
long target = 8;
List<long[]> result = new ArrayList<long[]>();
if (arr.length > 0 ) {
result = recursionHelper(arr, target);
}
System.out.println(result.size() > 0);
for(long[] l : result) {
System.out.println(Arrays.toString(l));
}
}
public static List<long[]> recursionHelper(long[] arr, long target) {
List<long[]> result = new ArrayList<long[]>();
if (arr.length == 0) return result;
for(int j = arr.length; j > 0; --j) {
long nextsom = recursiveAddition(Arrays.copyOfRange(arr, 0, j));
if (nextsom == target) result.add(Arrays.copyOfRange(arr, 0, j));
}
result.addAll(recursionHelper(Arrays.copyOfRange(arr, 1, arr.length), target));
return result;
}
public static long recursiveAddition(long[] arr) {
if ( arr.length == 1 ) return arr[0];
return arr[0] + recursiveAddition(Arrays.copyOfRange(arr, 1, arr.length));
}
}
Example output with arr = {1,2,4,1,3,5} and target = 8:
true
[1, 2, 4, 1]
[4, 1, 3]
[3, 5]
I try to write recursive program that return the biggest value - smallest value from array.
So I write this: (this return me the biggest value)
public static void main(String[] args) {
int arr[] = {1 , 5 , 11, -2};
System.out.println(SumOfBiggestMinusLowestValue(arr, 0));
}
private static int SumOfBiggestMinusLowestValue(int[] arr, int index) {
if (index == arr.length-1 ) {
return arr[index];
}
return Math.max (arr[index] ,SumOfBiggestMinusLowestValue(arr, index+1));
}
I though to do this to return big-min:
return Math.max (arr[index] ,SumOfBiggestMinusLowestValue(arr, index+1)) - Math.min(arr[index] ,SumOfBiggestMinusLowestValue(arr, index+1))
but it's not work its giving me 7 instead 13, what I missing?
and from yours experience guys,how to think recursively?
Essentially when recursing you want to have changing values and have it return the final results when a specific criteria is met
I modified your code so that you pass in the array, followed by the initial index and set the min and max value to the first value in the array. It will recurse down and check if the next value in the array is greater than or less than the min and max and set accordingly. It will stop once the index is equal to the length of the array and return the final results:
public static void main(String[] args) {
int arr[] = {1 , 5 , 11, -2};
System.out.println(pow(arr, 0, arr[0], arr[0]));
}
public static int pow(int[] arr, int index, int min, int max) {
if (index == arr.length) {
return max - min;
}
int val = arr[index];
int newMin = val < min ? val : min;
int newMax = val > max ? val : max;
return pow(arr, index + 1, newMin, newMax);
}
Another way to do it based off Taras Sheremeta suggestion is something as follows:
public static void main(String[] args) {
int arr[] = {1 , 5 , 11, -2};
System.out.println(largest(arr, 0) - smallest(arr, 0));
}
public static int smallest(int[] arr, int index) {
if (index == arr.length - 1) {
return arr[index];
}
return Math.min(arr[index], smallest(arr, index + 1));
}
public static int largest(int[] arr, int index) {
if (index == arr.length - 1) {
return arr[index];
}
return Math.max(arr[index], largest(arr, index + 1));
}
the functions will find their respective largest and smallest values recursively.
Looks like the is some logical error in recursion. In the pow method functions Math.max(...) and Math.min(...) get a value from the array as the first argument and NOT a value from an array as the second argument. The result of pow function IS NOT a value from the array.
public static void main(String[] args) {
int arr[] = {1 , 5 , 11, -2};
System.out.println(pow(arr, 0, arr[0], arr[0]));
}
private static int pow(int[] arr, int index, int max, int min) {
if (index == arr.length) {
return max - min;
}
max = Math.max(max, arr[index]);
min = Math.min(min, arr[index]);
return pow(arr, index + 1, max, min);
}
You can read more about How should you approach recursion?
I am trying to write a method that finds how many odd numbers are between first position and last position. The method accepts an array, and then two ints for the low and high position. This method needs to be made recursively. Here is what I have so far. Here is the method call and the int array. I'm getting an output of 1 but the answer should be 2.
int array [] = {5, 2, 5, 6, 3, 1};
int n = countOddsInRange(array, 1, 4)
public static int countOddsInRange(int [] a, int first, int last)
{
int count = 0;
if(first <= last)
{
countOddsInRange(a, a[first + 1], a[last]);
if(a[first] % 2 == 0)
{
count++;
}
}
return count;
}
You have some bugs in your code :
You are counting even numbers, not odd. Change your condition to if(a[first] % 2 != 0)
The recursive call should get indices of the array, not the values in those locations.
You should add the result of the recursive call to the total : count+=countOddsInRange(a, first + 1, last)
To summarize :
public static int countOddsInRange(int [] a, int first, int last)
{
int count = 0;
if(first <= last)
{
count+=countOddsInRange(a, first + 1, last);
if(a[first] % 2 != 0)
{
count++;
}
}
return count;
}
Your function should looks like :
public static int countOddNumber(int [] a, int first, int last){
return countOddNumber(a, first, last, 0);
}
public static int countOddNumber(int [] a, int first, int last, int count){
//in recursive function start with termination test.
if (first == last){
return count + isOdd(a[first]);
}
else{
return countOddNumber(a, first+1, last, count) + isOdd(a[first]);
}
}
public static int isOdd(int number){
if(number%2 == 0){return 1;}
else{return 0}
}
You should also add a test to check if first is lesser than last to avoid infinite loop ;)
PS : filter element whose mod(element,2) = 0 and then get the size of the collection. That method use functional style too, and use new Java8 feature. And is probably much more faster.
public class CountOddsInRange {
public static void main(String[] args) {
int array[] = {5, 2, 5, 6, 3, 1};
int n = countOddsInRange(array, 0, array.length - 1);
System.out.println("No of odds is " + n);
}
public static int countOddsInRange(int [] a, int first, int last)
{
int count = 0;
if(first <= last)
{
count+=countOddsInRange(a, first + 1, last);
if(a[first] % 2 != 0)
{
count++;
}
}
return count;
}
}
public class CountOddsInRange {
public static void main(String[] args) {
int array[] = {5, 2, 5, 6, 3, 1};
int n = countOddsInRange(array, 0, array.length - 1, 0);
System.out.println("No of odds is " + n);
}
public static int countOddsInRange(int[] a, int first, int last, int count) {
if (first <= last) {
if (a[first] % 2 != 0) {
count++;
}
return countOddsInRange(a, first + 1, last, count);
}
return count;
}
}
For one of the questions i was asked to solve, I found the max value of an array using a for loop, so i tried to find it using recursion and this is what I came up with:
public static int findMax(int[] a, int head, int last) {
int max = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
return findMax(a, head + 1, last);
} else {
return a[head];
}
}
So it works fine and gets the max value, but my question is : is it ok to have for the base case return a[head] and for the case when the value at the head is > the value at last?
You could just as easily do it with only one counter, just the index of the value you want to compare this time:
public static int findMax(int[] a, int index) {
if (index > 0) {
return Math.max(a[index], findMax(a, index-1))
} else {
return a[0];
}
}
This much better shows what is going on, and uses the default "recursion" layout, e.g. with a common base step. Initial call is by doing findMax(a, a.length-1).
It's actually much simpler than that. The base case is if you've reached the end of the array (the 'else' part of the ternary control block below). Otherwise you return the max of the current and the recursive call.
public static int findMax(int[] a) {
return findMax(a, 0);
}
private static int findMax(int[] a, int i) {
return i < a.length
? Math.max(a[i], findMax(a, i + 1))
: Integer.MIN_VALUE;
}
At each element, you return the larger of the current element, and all of the elements with a greater index. Integer.MIN_VALUE will be returned only on empty arrays. This runs in linear time.
I would solve this by dividing the array in to the half on each recursive call.
findMax(int[] data, int a, int b)
where a and b are array indices.
The stop condition is when b - a <= 1, then they are neighbours and the max is max(a,b);
The initial call:
findMax(int[] data, int 0, data.length -1);
This reduces the maximum recursion depth from N to log2(N).
But the search effort still stays O(N).
This would result in
int findMax(int[] data, int a, int b) {
if (b - a <= 1) {
return Math.max(data[a], data[b]);
} else {
int mid = (a+b) /2; // this can overflow for values near Integer.Max: can be solved by a + (b-a) / 2;
int leftMax = findMax(a, mid);
int rightMax = findMax(mid +1, b);
return Math.max(leftMax, rightMax);
}
}
I came across this thread and it helped me a lot. Attached is my complete code in both recursion and divide&conquer cases.
The run time for divide&conquer is slightly better than recursion.
//use divide and conquer.
public int findMaxDivideConquer(int[] arr){
return findMaxDivideConquerHelper(arr, 0, arr.length-1);
}
private int findMaxDivideConquerHelper(int[] arr, int start, int end){
//base case
if(end - start <= 1) return Math.max(arr[start], arr[end]);
//divide
int mid = start + ( end - start )/2;
int leftMax =findMaxDivideConquerHelper(arr, start, mid);
int rightMax =findMaxDivideConquerHelper(arr, mid+1, end);
//conquer
return Math.max( leftMax, rightMax );
}
// use recursion. return the max of the current and recursive call
public int findMaxRec(int[] arr){
return findMaxRec(arr, 0);
}
private int findMaxRec(int[] arr, int i){
if (i == arr.length) {
return Integer.MIN_VALUE;
}
return Math.max(arr[i], findMaxRec(arr, i+1));
}
What about this one ?
public static int maxElement(int[] a, int index, int max) {
int largest = max;
while (index < a.length-1) {
//If current is the first element then override largest
if (index == 0) {
largest = a[0];
}
if (largest < a[index+1]) {
largest = a[index+1];
System.out.println("New Largest : " + largest); //Just to track the change in largest value
}
maxElement(a,index+1,largest);
}
return largest;
}
I know its an old Thread, but maybe this helps!
public static int max(int[] a, int n) {
if(n < 0) {
return Integer.MIN_VALUE;
}
return Math.max(a[n-1], max(a, n - 2));
}
class Test
{
int high;
int arr[];
int n;
Test()
{
n=5;
arr = new int[n];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
high = arr[0];
}
public static void main(String[] args)
{
Test t = new Test();
t.findHigh(0);
t.printHigh();
}
public void printHigh()
{
System.out.println("highest = "+high);
}
public void findHigh(int i)
{
if(i > n-1)
{
return;
}
if(arr[i] > high)
{
high = arr[i];
}
findHigh(i+1);
return;
}
}
You can do it recursively as follows.
Recurrent relation it something like this.
f(a,n) = a[n] if n == size
= f(a,n+1) if n != size
Implementation is as follows.
private static int getMaxRecursive(int[] arr,int pos) {
if(pos == (arr.length-1)) {
return arr[pos];
} else {
return Math.max(arr[pos], getMaxRecursive(arr, pos+1));
}
}
and call will look like this
int maxElement = getMaxRecursive(arr,0);
its not okay!
your code will not find the maximum element in the array, it will only return the element that has a higher value than the elements next to it, to solve this problem,the maximum value element in the range can be passed as argument for the recursive method.
private static int findMax(int[] a, int head, int last,int max) {
if(last == head) {
return max;
}
else if (a[head] > a[last]) {
max = a[head];
return findMax(a, head, last - 1, max);
} else {
max = a[last];
return findMax(a, head + 1, last, max);
}
}
Optimized solution
public class Test1 {
public static int findMax(int[] a, int head, int last) {
int max = 0, max1 = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
max = findMax(a, head + 1, last);
} else
max = findMax(a, head, last - 1);
if (max >= max1) {
max1 = max;
}
return max1;
}
public static void main(String[] args) {
int arr[] = {1001, 0, 2, 1002, 2500, 3, 1000, 7, 5, 100};
int i = findMax(arr, 0, 9);
System.out.println(i);
}
}
Thanks #Robert Columbia for the suggestion!
Update: This following function is going to recursively start from index 0 and it will keep adding to this index value till it's equal to the Length of the array, if it's more we should stop and return 0. Once we're doing that, we need to get the max of every two items in the array so, for example:
A = [1 , 2 , 3 ];
A[0] ( 1 ) vs A[1] ( 2 ) = 2
A[1] ( 2 ) vs A[2] ( 3 ) = 3
Max(2,3) = 3 ( The answer )
public int GetMax(int [] A, int index) {
index += 1;
if (index >= A.Length) return 0;
return Math.Max(A[index], GetMax(A, index + 1));
}
static int maximumOFArray(int[] array,int n) {
int max=Integer.MIN_VALUE;
if(n==1) return array[0];
else
max=maximumOFArray(array, --n);
max= max>array[n] ? max : array[n];
return max;
}
private static int getMax(int [] arr, int idx) {
if (idx==arr.length-1 ) return arr[idx];
return Math.max(arr[idx], getMax (arr,idx+1 ));
}
public class FindMaxArrayNumber {
public static int findByIteration(int[] array) {
int max = array[0];
for (int j : array) {
max = Math.max(j, max);
}
return max;
}
public static int findByRecursion(int[] array, int index) {
return index > 0
? Math.max(array[index], findByRecursion(array, index - 1))
: array[0];
}
public static void main(String[] args) {
int[] array = new int[]{1, 2, 12, 3, 4, 5, 6};
int maxNumberByIteration = findByIteration(array);
int maxNumberByRecursion = findByRecursion(array, array.length - 1);
System.out.println("maxNumberByIteration: " + maxNumberByIteration);
System.out.println("maxNumberByRecursion: " + maxNumberByRecursion);
// Outputs:
// maxNumberByIteration: 12
// maxNumberByRecursion: 12
}
}
int maximum = getMaxValue ( arr[arr.length - 1 ], arr, arr.length - 1 );
public static int getMaxValue ( int max, int arr[], int index )
{
if ( index < 0 )
return max;
if ( max < arr[index] )
max = arr[index];
return getMaxValue ( max, arr, index - 1 );
}
I felt that using a tracker for current maximum value would be good.