Recursion Problem - given array n and a number k - java

Given an array size n, and a positive number max(max represent the range of the numbers that we can use to place in the array).
I would like to count how many combinations of sorted numbers I can place in the array.
For example :
If n = 3, max = 2.(the only numbers we can use is 1/2 as max is 2) so there are 4 combinations of sorted arrays
1. {1,1,1}
2. {1,1,2}
3. {1,2,2}
4. {2,2,2}
I wrote some code and succeed to pass this specific example but any other example that max > 2 doesn't return the correct answer.
the problem as I identify it is when the recursion reaches the last index it doesn't try a third number it just folds back.
my code :
private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {
// If the value is bigger then max return 0
if(numToMax > max) {
return 0;
}
if (numToMax < prevNum) {
return 0;
}
//If Index reached the end of the array return 1
if(index == n) {
return 1;
}
int sortTwo = howManySorted(n, max, index+1, numToMax, numToMax);
int sortOne = howManySorted(n, max, index+1, numToMax+1, numToMax);
return ((sortOne+sortTwo));
}
public static int howManySorted(int n, int max) {
return howManySorted(n, max, 0, 1, 0);
}

start with "{1," and add elements "{1,1" and/or value "{2," with each recursion. when it reach n elements array we add to the counter. n is the number of elements in the array max is the maximal value for each element. minimal is 1. element is the current cell in the array being manipulated. we start with 1 (in actual array means 0). value is the current value of the current element. we start with 1.
// external function according to the given question
public static int count (int n, int max)
{
return count(n,max, 1, 1);
}
private static int count (int n, int max, int element, int value)
{
int counter = 0;
// only if our array reached n elements we count the comination
if (element == n)
counter++;
else // we need to continue to the next element with the same value
counter += count(n, max, element +1, value);
if (value < max) // if our current element didn't reach max value
counter += count (n, max, element, value+1);
return counter;
}

I think you would need to change your two recursive calls (this is why it only reaches value 2) and do as many calls as your max parameter:
private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {
// If the value is bigger then max return 0
if (numToMax > max) {
return 0;
}
if (numToMax < prevNum) {
return 0;
}
//If Index reached the end of the array return 1
if (index == n) {
return 1;
}
int result = 0;
for (int i = 0; i < max; i++)
result += howManySorted(n, max, index + 1, numToMax + i, numToMax);
return result;
}

I believe you can simplify your answer to something like this
private static long howManySorted(int length, int min, int max) {
if (length == 1) {
return max - min + 1;
}
// if (min == max) {
// return 1;
// }
long result = 0;
for (int i = min; i <= max; i++) {
result += howManySorted(length - 1, i, max);
}
return result;
}
public static long howManySorted(int length, int max) {
if ((length < 1) || (max < 1)) {
throw new IllegalArgumentException();
}
return howManySorted(length, 1, max);
}
Client should call the public method.
So as you can see terminate conditions are when remaining length is 1, or min reaches max. Even removing the second terminate condition doesn't change the result, but can improve the performance and number of recursions.

Just test my code, I think it figures out your problem:
class Test {
private static int howManySorted(int n, int max) {
//Better time complexity if u use dynamic programming rather than recursion.
if (n == 0) return 1;
int res = 0; // "res" can be a very large.
for (int i = n; i >= 1; i--) {
for (int j = max; j >= 1;j--) {
res += howManySorted(i-1, j-1);
}
}
return res;
}
public static void main(String[] args) {
System.out.println(howManySorted(3, 2));
}
}
This code will run faster if you use dynamic programming and be careful about the answer, it could be a very large integer.

You guys are forgetting he needs a solution using only recursion.
Probably a Java assignment for a CS class.
I also had that question.
This is the answer I came up with:
/**
* #param n Number of values in the array
* #param max Maximum value of each cell in the array
* #return int
*/
public static int howManySorted(int n, int max) {
return howManySorted(max, max, 1, n - 1);
}
/**
*
* #param value The current value
* #param max The maximum possible value (not allowed to use global parameters, so the parameter value always stays the same)
* #param min The minimum value allowed in this index. Determined by the value of the previous index (when first called, use value 1)
* #param index The index of the value being manipulated
* #return
*/
public static int howManySorted(int value, int max, int min, int index) {
//If any of these cases are found true, it means this value is invalid, don't count it
if (index < 0 || value < min) {
return 0;
}
//First lower the value in the same index, the result is the number of valid values from that branch
int lowerValue = howManySorted(value - 1, max, min, index);
//Now check all the valid values from the next index - value is max-1 to prevent counting twice some numbers
int lowerIndex = howManySorted(max - 1, max, value, index - 1);
//Return 1 (this number we are at right now) + all of its children
return 1 + lowerValue + lowerIndex;
}

I treated each series (e.g. '1,1,2') as an array, so at the beginning I wrote something like that:
public static void main(String[] args)
{
System.out.println(howManySorted(3, 2, 1, "")); // 4
System.out.println(howManySorted(2, 3, 1, "")); // 6
}
private static int howManySorted(int n, int max, int index, String builder)
{
if (max == 0) // if we exceeds max, return 0.
return 0;
if (n == 0) // num represents how many individual numbers we can have, if it is zero it means we have the required length (e.g. if n = 3, we have 'x1,x2,x3').
{
System.out.println(builder.substring(0, builder.length() - 2));
return 1;
}
int r1 = howManySorted(n - 1, max, index, builder + index + ", "); // i added additional var 'index' to represent each number in the list: (1,1,1)
int r2 = howManySorted(n, max - 1, index + 1, builder); // I'm increasing the index and decreasing the max (1,1,**2**)
return r1 + r2;
}
But eventually, we don't need the 'index' nor the 'builder', they were just to emphasize how I solved it...
public static void main(String[] args)
{
int max = 2, n = 3;
System.out.println(howManySorted(n, max)); // 4
int max1 = 3, n1 = 2;
System.out.println(howManySorted(n1, max1)); // 6
}
public static int howManySorted(int n, int max)
{
if (max == 0) // if we exceeds max, return 0.
return 0;
if (n == 0) // like we said, num represents how many individual numbers we can have, if it is zero it means we have the required length (e.g. if n = 3, we have 'x1,x2,x3').
return 1;
int r1 = howManySorted(n - 1, max);
int r2 = howManySorted(n, max - 1);
return r1 + r2;
}

Related

how to binary search one specific element in an array?

i have a binary search algorithm set up but i didn't know how to make it work
like what where im suppose to tell it to look for an element and show if it is found or not
any tip would help
thank you
public static int search(int arr[], int x)
{
int startIndex = 0 ;
int endIndex = arr.length-1;
while ( startIndex <=endIndex){
int midpoint = (startIndex + endIndex )/2;
if(arr[midpoint]==x)
return midpoint;
else if(arr[midpoint]<x)
startIndex=midpoint+1;
else
endIndex = midpoint = -1;
}
return -1;
}
//here i want to make it search for 6
public static void main (String [] args ){
search v = new search();
int [] test = {1,99,6,32,4,6,33,90};
for (int element: test) {
System.out.println("the elements of array: "+ element);
int x = 6;
int result=v.binarySearch();
}
Binary Search works as, Search a sorted array by repeatedly dividing the search interval in half. Begin with an interval covering the whole array. If the value of the search key is less than the item in the middle of the interval, narrow the interval to the lower half. Otherwise, narrow it to the upper half. Repeatedly check until the value is found or the interval is empty.
int[] test = {1, 99, 6, 32, 4, 6, 33, 90};
int num = 6;
Arrays.sort(test);
System.out.println(binarySearch(test, num, 0, test.length));
logic for the binary search is given below as,
public int binarySearch(int arr[], int num, int min, int max) {
if (min > max) {
return -1;
}
int mid = min + (max - min) / 2;
if (arr[mid] == num) {
return mid;
} else if (arr[mid] < num) {
return binarySearch(arr, num, mid + 1, max);
}
return binarySearch(arr, num, min, mid - 1);
}

return recursivly the biggest values minus lowest value from array

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?

time complexity - Binary Indexed Tree

I am writing a binary indexed tree. As documentation, it requires nlogn time to pre process. But I am not able to understand why.
In my case I am constructing the tree from the Array, which should take 2n time, as first time traversing the array once to make it a Binary tree and then to update sum I am again traversing the tree in POST order fashion. so total 2n, not nlogn.
Can anybody explain why it needs nlogn time to pre-process the binary indexed tree.
public class BITree {
private class BTN {
int data;
int index;
BTN left,right;
public BTN(int data) {
this.data = data;
}
}
BTN head = null;
public BTN toBT(int[] arr,int start,int end){
if(start <= end){
int mid = start + (end - start)/2;
BTN btn = new BTN(arr[mid]);
btn.index = mid+1;
btn.left = toBT(arr,start,mid-1);
btn.right = toBT(arr,mid+1,end);
return btn;
}
return null;
}
public int sumAtIndex(BTN btn,int index){
int sum = 0;
if(index < btn.index)
sum += sumAtIndex(btn.left,index);
else if(index > btn.index) {
sum += btn.data + sumAtIndex(btn.right, index);
}
if(btn.index == index)
return btn.data + sum;
return sum;
}
public int replaceSum(BTN btn){
if(btn == null){
return 0;
}
int l = replaceSum(btn.left);
int r = replaceSum(btn.right);
int sum = btn.data + l + r;
btn.data += l;
return sum;
}
void inOrder(BTN btn){
if(btn != null) {
inOrder(btn.left);
System.out.print((btn.index+":"+btn.data)+",");
inOrder(btn.right);
}
}
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,3,3};
BITree s2 = new BITree();
BTN btn = s2.toBT(arr,0,arr.length-1);
s2.replaceSum(btn);
s2.inOrder(btn);
System.out.println();
System.out.println(s2.sumAtIndex(btn,3));
}
}
This question is a duplicate of :Is it possible to build a Fenwick tree in O(n)?
#Thilo , Thanks for pointing out the optimized way for preprocessing the the BIT. Which can be done in O(n) time.
https://en.wikipedia.org/wiki/Talk:Fenwick_tree
https://stackoverflow.com/a/31070683/3080158
#SanketMakani, Thanks for sharing the link, it explains the BIT very well.
here is the working code, with O(n) pre processing time.
package com.rabin;
import java.util.StringJoiner;
/**
*
*/
public class BITree {
/**
* O(logn)
* #param arr
* #param index
* #param val
*/
void update(int arr[],int index, int val)
{
index++;
for(; index <= arr.length-1; index += index&-index)
arr[index] += val;
}
/**
* O(logn)
* #param arr
* #param noOfElements
* #return
*/
int query(int[] arr,int noOfElements)
{
int sum = 0;
for(; noOfElements > 0; noOfElements -= noOfElements&-noOfElements)
sum += arr[noOfElements-1];
return sum;
}
/**
* O(n)
* #param arr
*/
void toBIT(int[] arr){
int n = arr.length;
for(int i=1;i<=n;i++){
int j = i+ (i & -i);
if(j <= n)
arr[j-1] += arr[i-1];
}
}
static String arrayToString(int[] arr){
StringJoiner sj = new StringJoiner(",","[","]");
for(int i = 0; i< arr.length ;i++){
sj.add(String.valueOf(arr[i]));
}
return sj.toString();
}
public static void main(String[] args) {
int[] arr = {5,1,6,4,2,3,3};
BITree bit = new BITree();
System.out.println("Original Array:" +arrayToString(arr));
bit.toBIT(arr);
System.out.println("BIT Array:" +arrayToString(arr));
System.out.println("Sum of first 5 nos : "+ bit.query(arr,5));
bit.update(arr,0,8);
System.out.println("Sum of first 5 nos after update : "+ bit.query(arr,5));
}
}
#RBanerjee nicely written code, It is good to implement the BIT with one additional index, which helps in code comprehension. Plus it also signifies one additional thing - the least significant 1 bit from the BIT index indicates as to how many elements does the particular index stores. For e.g. index = 2 (010) can signify index 2 in BIT holds the values of 2 elements, similarly 4 (100) for 4, 6 (110) stores 2 values (namely, index 5 and 6) and so on.
Additionally, in your update method you aren't updating the value per se. You are adding the given value. Which I do not think signifies the meaning of update. It is a very subjective discussion, but I think of it as an update and not an increment. So, if the index 5 originally holds value 2, and when I want to update it to -1, it means the value after the update at index 5 is -1 and not 1.
As an extra step, it is good to provide a way to query the ranges in the array. For e.g. what is the value between indices 2 and 5 (inclusive).
<!-- language: java -->
package DataStructureImplementation;
import java.util.StringJoiner;
public class BinaryIndexedTree {
private final int[] bit;
private final int[] nums;
private final int n;
public BinaryIndexedTree(int[] nums) {
n = nums.length;
bit = new int[n + 1];
this.nums = nums;
System.arraycopy(nums, 0, bit, 1, nums.length);
build();
}
/**
* Builds a binary indexed tree in O(n) time.
*/
private void build() {
int j;
for (int i = 1; i <= n; ++i) {
j = i + (i & -i);
if (j <= n) bit[j] += bit[i];
}
}
/**
* Updates an indexed item in the original array to the given value.
* Also updates the values in the 'BIT' in O(logn) time.
* #param index - index of the item to update
* #param value - value to update to
*/
public void update(int index, int value) {
int diff = value - nums[index];
nums[index] = value;
index++;
while (index <= n) {
bit[index] += diff;
index += (index & -index);
}
}
/**
* Queries the sum of the first 'K' indices in the original array in O(logn) time.
* #param k - the number of items to aggregate.
* #return - the sum of first 'K' numbers in the original array.
* #throws Exception - if 'K' is out of bounds.
*/
public int query(int k) throws Exception {
if (k < 0 || k > n) throw new Exception("Invalid query range : " + k);
int sum = 0;
while (k > 0) {
sum += bit[k];
k -= (k & -k);
}
return sum;
}
/**
* Queries the sum of numbers from the original array between index1 and index2 (inclusive) in O(logn) time.
* #param index1 - left index.
* #param index2 - right index.
* #return - the sum of numbers between the given ranges.
* #throws Exception - if range is out of bounds.
*/
public int queryRange(int index1, int index2) throws Exception {
return query(index2 + 1) - query(index1);
}
/**
* Helper method to print the array contents.
* #param nums - the array to print.
* #return - the contents of the array as string.
*/
static String arrayToString(int[] nums){
StringJoiner stringJoiner = new StringJoiner(",","[","]");
for (int n : nums) {
stringJoiner.add(String.valueOf(n));
}
return stringJoiner.toString();
}
public static void main(String[] args) throws Exception {
int[] nums = {5,8,5,4,2,3};
BinaryIndexedTree binaryIndexedTree = new BinaryIndexedTree(nums);
System.out.println("Original Array : " + arrayToString(nums));
System.out.println("BIT Array : " + arrayToString(binaryIndexedTree.bit));
System.out.println("Sum of first 5 nos : " + binaryIndexedTree.query(5));
binaryIndexedTree.update(4,-1);
System.out.println("Original Array after update : " + arrayToString(nums));
System.out.println("BIT Array after update : " + arrayToString(binaryIndexedTree.bit));
System.out.println("Sum of first 5 nos after update : " + binaryIndexedTree.query(5));
System.out.println("Sum of numbers in range 2-5 : " + binaryIndexedTree.queryRange(2, 5));
}
}

Finding Max value in an array using recursion

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.

Java Range find difference between largest and smallest int

I'm having trouble figuring out how exactly to make it find the max number and minimum number in the array.
Write a method range that accepts an ArrayList of integers as a parameter and that returns the range of values contained in the list, which is defined as 1 more than the difference between the largest and smallest elements. For example if a variable called list stores the following values:
[18, 14, 29, 12, 7, 25]
The call of range(list) should return 23, because this is one more than the largest difference between any pair of values (29 - 7 + 1 = 23). An empty list is defined to have a range of 0.
So far I have this:
public static int range(ArrayList<Integer> list)
{
int min = 0;
int max = 0;
int range = 0;
for (int i: list)
{
if (list.size() > 0)
{
range = max - min + 1;
}
}
return range;
}
Thank you VERY MUCH!
You have more than method to achive this goal.
Using Collections (more compact but expensive because it iterates two times on the list, one to find the max and one to find the min):
public static int range(final ArrayList<Integer> list) {
if (list.isEmpty()) {
return 0;
} else {
return (Collections.max(list) - Collections.min(list)) + 1;
}
}
Or using your own algorithm like this (more code but finds min and max with just one loop):
public static int range(final ArrayList<Integer> list) {
if (list.isEmpty()) {
return 0;
} else {
int max = list.get(0);
int min = list.get(0);
for (final int i : list) {
if (i > max) {
max = i;
} else if (i < min) {
min = i;
}
}
return (max - min) + 1;
}
}
Why not use Collections.min and Collections.max
int difference = Collections.max(list) - Collections.min(list);
You never calculate the max and the min value in your loop.
Hint : In this loop, find the max and the min value. Then calculate the range and return it.
int min = 0;
int max = 0;
for (int i: list){
//find max and min here
}
return max - min + 1;
This task only needs two lines:
Collections.sort(list);
return list.isEmpty() ? 0 : list.get(list.size() - 1) - list.get(0);
Use the java JDK's API to do the heavy lifting for you
It's how you look at a problem that's important
Less code is good (as long as it's legible
You could sort it and then peek fist and last item.
public static int range(List<Integer> input)
{
if(input == null || input.size() == 0) throw new IllegalArgumentException("");
if(input.size() == 1) return 0;
List<Integer> copy = new ArrayList(input);
Collections.sort(copy);
int min = copy.get(0);
int max = copy.get(copy.lenght-1);
return max - min;
}
This is not a perfect solution as list may contain nulls.
You can start with simple comparison.
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for(Integer integer : input) {
if(i == null) continue;
int i = integer.intValue();
if(i < min) {
min = i;
}
if(i > max) {
max = i;
}
}
return max - min;
public static int range(ArrayList<Integer> list){
int min = list.get(0);
int max = list.get(0);
for (int i = 0; i < list.size(); i++){
if (list.get(i) > max)
max = list.get(i);
if ((list.get(i) < min))
min = list.get(i);
}
return max-min+1;
}
I have another solution that works. Let me explain how it works.
The first if statement checks for the empty list case.
Afterwards, I declared an integer variable int diff to return at the end. Two numbers are selected by the two for loops where the first one starts at index 0 while the nested loop starts at index 1 so that no same numbers are considered when looping through. The difference between two numbers are obtained using the formula declared as int calc. Since we're looking for the biggest difference between two numbers, we set diff = calc and keep it updating.
Lastly, we return diff + 1 as the problem stated.
public int range(ArrayList<Integer> list) {
if (list.size() == 0) {
return 0;
}
int diff = 0;
for (int i = 0; i < list.size(); i++) {
for (int j = 1; j < list.size(); j++) {
int calc = Math.abs(list.get(i) - list.get(j));
if (diff < calc) {
diff = calc;
}
}
}
return diff + 1;
}

Categories

Resources