Maximum Sum SubArray - java

I am trying to find the contiguous subarray within an array which has the largest sum. So, for the array
{5, 15, -30, 10, -5, 40, 10}
the maximum sum possible using those numbers contiguously would be 55, or (10 + (-5) + 40 + 10) = 55. The program below outputs the maximum sum of 55, however, the problem I am trying to figure out is how to print the sequence that produces this 55. In other words, how can I print out the 10, -5, 40, and 10?
public static void main(String[] args) {
int[] arr = {5, 15, -30, 10, -5, 40, 10};
System.out.println(maxSubsequenceSum(arr));
}
public static int maxSubsequenceSum(int[] X) {
int max = X[0];
int sum = X[0];
for (int i = 1; i < X.length; i++) {
sum = Math.max(X[i], sum + X[i]);
max = Math.max(max, sum);
}
return max;
}
I was thinking of creating an ArrayList to store the sum values at every index of i, so the ArrayList would look like (5, 20, -10, 10, 5, 45, 55). And then I was planning on clearing the ArrayList from index 0 to the first negative number in the list, however, this only solves the problem for this specific example, but if I change the original array of numbers, this solution won't work.

You can replace Math.Max functions by if statements and update start and end index of the best subarray. Pascal version:
if X[i] > sum + X[i] then begin
sum := X[i];
start := i;
end
else
sum := sum + X[i];
if max < sum then begin
max := sum;
finish := i;
end;

You can track the starting and ending indexes of the current best subarray in your loop. Instead of using max() to compute sumand max, just do the following :
int sum_start = 0, sum_end = 0, start = 0, end = 0;
// In the for loop
if (X[i] > sum + X[i]) {
sum = X[i];
sum_start = i;
sum_end = i;
} else {
++sum_end;
}
if (sum > max) {
start = sum_start;
end = sum_end;
max = sum;
}

there is an o(n) solution, a single for loop through the array and reset your sub-sequence whenever your current total is below 0.
{5, 15, -30, 10, -5, 40, 10}
5 + 15 = 20
20 - 30 = -10 (reset sub-sequence)
10 -5 +40 +10 = 55
end. 55 is max sub-sequence
edit: to get subsequence...
whenever you change max, update your subsequence
current left index changes only when u reset
current right index changes every iteration
new max -> save current left and right index...

It can be done by capturing the start and end while identifying maximum sub-array as follows:
Code
package recursion;
import java.util.Arrays;
public class MaximumSubArray {
private static SubArray maxSubArray(int[] values, int low, int high) {
if (low == high) {
// base condition
return new SubArray(low, high, values[low]);
} else {
int mid = (int) (low + high) / 2;
// Check left side
SubArray leftSubArray = maxSubArray(values, low, mid);
// Check right side
SubArray rightSubArray = maxSubArray(values, mid + 1, high);
// Check from middle
SubArray crossSubArray = maxCrossSubArray(values, low, mid, high);
// Compare left, right and middle arrays to find maximum sub-array
if (leftSubArray.getSum() >= rightSubArray.getSum()
&& leftSubArray.getSum() >= crossSubArray.getSum()) {
return leftSubArray;
} else if (rightSubArray.getSum() >= leftSubArray.getSum()
&& rightSubArray.getSum() >= crossSubArray.getSum()) {
return rightSubArray;
} else {
return crossSubArray;
}
}
}
private static SubArray maxCrossSubArray(int[] values, int low, int mid,
int high) {
int sum = 0;
int maxLeft = low;
int maxRight = high;
int leftSum = Integer.MIN_VALUE;
for (int i = mid; i >= low; i--) {
sum = sum + values[i];
if (sum > leftSum) {
leftSum = sum;
maxLeft = i;
}
}
sum = 0;
int rightSum = Integer.MIN_VALUE;
for (int j = mid + 1; j <= high; j++) {
sum = sum + values[j];
if (sum > rightSum) {
rightSum = sum;
maxRight = j;
}
}
SubArray max = new SubArray(maxLeft, maxRight, (leftSum + rightSum));
return max;
}
static class SubArray {
private int start;
private int end;
private int sum;
public SubArray(int start, int end, int sum) {
super();
this.start = start;
this.end = end;
this.sum = sum;
}
public int getStart() { return start; }
public void setStart(int start) { this.start = start; }
public int getEnd() { return end; }
public void setEnd(int end) { this.end = end; }
public int getSum() { return sum; }
public void setSum(int sum) { this.sum = sum; }
#Override
public String toString() {
return "SubArray [start=" + start + ", end=" + end + ", sum=" + sum + "]";
}
}
public static final void main(String[] args) {
int[] values = { 5, 15, -30, 10, -5, 40, 10 };
System.out.println("Maximum sub-array for array"
+ Arrays.toString(values) + ": " + maxSubArray(values, 0, 6));
}
}
Output
Maximum sub-array for array[5, 15, -30, 10, -5, 40, 10]: SubArray [start=3, end=6, sum=55]
Solution can be downloaded from https://github.com/gosaliajigar/Programs/blob/master/src/recursion/MaximumSubArray.java

Two subarray are
[1, 2, 3]
and [4, 9] excluding the negative number
The max sub array here is [ 4, 5]
so the output is 9
Here is the code
public class MaxSubArray{
static void sumM(int a[], int n){
int s1 = Integer.MAX_VALUE;
int k = Integer.MAX_VALUE;
int sum = 0;
int s2 = 0;
for(int i=0;i<n;i++){
if(a[i]<s1){
if(a[i]<0){
k = Math.min(a[i],s1);
}
}
if(a[i]>k){
sum+=a[i];
}
if(a[i]<k){
if(a[i]<0){
continue;
}
s2+=a[i];
}
}
if(sum>s2){
System.out.println(sum);
}
else{
System.out.println(s2);
}
}
public static void main(String[] args){
int a[] = {1,2,3,-7,4,5};
int n = a.length;
sumM(a,n);
}
}

public static int kadane(int[] A) {
int maxSoFar = 0;
int maxEndingHere = 0;
// traverse the given array
for (int i: A) {
// update the maximum sum of subarray "ending" at index `i` (by adding the
// current element to maximum sum ending at previous index `i-1`)
maxEndingHere = maxEndingHere + i;
// if the maximum sum is negative, set it to 0 (which represents
// an empty subarray)
maxEndingHere = Integer.max(maxEndingHere, 0);
// update the result if the current subarray sum is found to be greater
maxSoFar = Integer.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}

var maxSequence = function(arr){
// ...
if (arr.every((ele) => ele >= 0)) {
return arr.reduce((sum, ele) => sum + ele, 0);
} else if (arr.every((ele) => ele < 0)) {
return 0;
//for me the maximum would be the biggest negative number
//arr.reduce((max, elm) => (max > elm ? max : elm))
} else if (arr === [0]) {
return 0;
} else {
let maxSum = [];
let currentSum = 0;
for (let i = 0; i < arr.length; i++) {
currentSum = Math.max(arr[i], currentSum + arr[i]);
maxSum.push(currentSum);
}
return maxSum.reduce((max, elm) => (max > elm ? max : elm));
}
}

you need to sum all possible sub array. to do that, you can do this code
public static int maxSubsequenceSum(int[] X) {
int max = 0;
boolean max_init = false;
int max_from=0;
int max_to=0; // this is not included
for (int i = 0; i < X.length; i++) {
for (int j = i + 1; j < X.length + 1; j++) {
int total = 0;
for (int k = i; k < j; k++) {
total += X[k];
}
if (total > max || !max_init){
max = total;
max_init = true;
max_from = i;
max_to = j;
}
}
}
for (int i=max_from;i<max_to;i++)
System.out.print(X[i]+",");
System.out.println();
return max;
}

Related

Find the max value of the same length nails after hammered

I'm trying to solve this problem:
Given an array of positive integers, and an integer Y, you are allowed to replace at most Y array-elements with lesser values. Your goal is for the array to end up with as large a subset of identical values as possible. Return the size of this largest subset.
The array is originally sorted in increasing order, but you do not need to preserve that property.
So, for example, if the array is [10,20,20,30,30,30,40,40,40] and Y = 3, the result should be 6, because you can get six 30s by replacing the three 40s with 30s. If the array is [20,20,20,40,50,50,50,50] and Y = 2, the result should be 5, because you can get five 20s by replacing two of the 50s with 20s.
Below is my solution with O(nlogn) time complexity. (is that right?) I wonder if I can further optimize this solution?
Thanks in advance.
public class Nails {
public static int Solutions(int[] A, int Y) {
int N = A.length;
TreeMap < Integer, Integer > nailMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < N; i++) {
if (!nailMap.containsKey(A[i])) {
nailMap.put(A[i], 1);
} else {
nailMap.put(A[i], nailMap.get(A[i]) + 1);
}
}
List < Integer > nums = nailMap.values().stream().collect(Collectors.toList());
if (nums.size() == 1) {
return nums.get(0);
}
//else
int max = nums.get(0);
int longer = 0;
for (int j = 0; j < nums.size(); j++) {
int count = 0;
if (Y < longer) {
count = Y + nums.get(j);
} else {
count = longer + nums.get(j);
}
if (max < count) {
max = count;
}
longer += nums.get(j);
}
return max;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String[] input = scanner.nextLine().replaceAll("\\[|\\]", "").split(",");
System.out.println(Arrays.toString(input));
int[] A = new int[input.length - 1];
int Y = Integer.parseInt(input[input.length - 1]);
for (int i = 0; i < input.length; i++) {
if (i < input.length - 1) {
A[i] = Integer.parseInt(input[i]);
} else {
break;
}
}
int result = Solutions(A, Y);
System.out.println(result);
}
}
}
A C++ implementation would like the following where A is the sorted pin size array and K is the number of times the pins can be hammered.
{1,1,3,3,4,4,4,5,5}, K=2 should give 5 as the answer
{1,1,3,3,4,4,4,5,5,6,6,6,6,6,6}, K=2 should give 6 as the answer
int maxCount(vector<int>& A, int K) {
int n = A.size();
int best = 0;
int count = 1;
for (int i = 0; i < n-K-1; i++) {
if (A[i] == A[i + 1])
count = count + 1;
else
count = 1;
if (count > best)
best = count;
}
int result = max(best+K, min(K+1, n));
return result;
}
Since the array is sorted to begin with, a reasonably straightforward O(n) solution is, for each distinct value, to count how many elements have that value (by iteration) and how many elements have a greater value (by subtraction).
public static int doIt(final int[] array, final int y) {
int best = 0;
int start = 0;
while (start < array.length) {
int end = start;
while (end < array.length && array[end] == array[start]) {
++end;
}
// array[start .. (end-1)] is now the subarray consisting of a
// single value repeated (end-start) times.
best = Math.max(best, end - start + Math.min(y, array.length - end));
start = end; // skip to the next distinct value
}
assert best >= Math.min(y + 1, array.length); // sanity-check
return best;
}
First, iterate through all the nails and create a hash H that stores the number of nails for each size. For [1,2,2,3,3,3,4,4,4], H should be:
size count
1 : 1
2 : 2
3 : 3
4 : 3
Now create an little algorithm to evaluate the maximum sum for each size S, given Y:
BestForSize(S, Y){
total = H[S]
while(Y > 0){
S++
if(Y >= H[S] and S < biggestNailSize){
total += H[S]
Y -= H[S]
}
else{
total += Y
Y = 0
}
}
return total;
}
Your answer should be max(BestForSize(0, Y), BestForSize(1, Y), ..., BestForSize(maxSizeOfNail, Y)).
The complexity is O(n²). A tip to optimize is to start from the end. For example, after you have the maximum value of nails in the size 4, how can you use your answer to find the maximum number of size 3?
Here is my java implementation: First I build a reversed map of each integer and its occurence for example {1,1,1,1,3,3,4,4,5,5} would give {5=2, 4=2, 3=2, 1=4}, then for each integer I calculate the max occurence that we can get of it regarding the K and the occurences of the highest integers in the array.
public static int ourFunction(final int[] A, final int K) {
int length = A.length;
int a = 0;
int result = 0;
int b = 0;
int previousValue = 0;
TreeMap < Integer, Integer > ourMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < length; i++) {
if (!ourMap.containsKey(A[i])) {
ourMap.put(A[i], 1);
} else {
ourMap.put(A[i], ourMap.get(A[i]) + 1);
}
}
for (Map.Entry<Integer, Integer> entry : ourMap.entrySet()) {
if( a == 0) {
a++;
result = entry.getValue();
previousValue = entry.getValue();
} else {
if( K < previousValue)
b = K;
else
b = previousValue;
if ( b + entry.getValue() > result )
result = b + entry.getValue();
previousValue += entry.getValue();
}
}
return result;
}
Since the array is sorted, we can have an O(n) solution by iterating and checking if current element is equals to previous element and keeping track of the max length.
static int findMax(int []a,int y) {
int n = a.length,current = 1,max = 0,diff = 0;
for(int i = 1; i< n; i++) {
if(a[i] == a[i-1]) {
current++;
diff = Math.min(y, n-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
given int array is not sorted than you should sort
public static int findMax(int []A,int K) {
int current = 1,max = 0,diff = 0;
List<Integer> sorted=Arrays.stream(A).sorted().boxed().collect(Collectors.toList());
for(int i = 1; i< sorted.size(); i++) {
if(sorted.get(i).equals(sorted.get(i-1))) {
current++;
diff = Math.min(K, sorted.size()-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
public static void main(String args[]) {
List<Integer> A = Arrays.asList(3,1,5,3,4,4,3,3,5,5,5,1);
int[] Al = A.stream().mapToInt(Integer::intValue).toArray();
int result=findMax(Al, 5);
System.out.println(result);
}

I am not sure what is wrong with my quick select method

So I tried to write a code to select kth smallest element in a given input integer array using quick sort, but for some reason as you can see in the code below,
public static int partition(int[] input, int first, int end) {
int pivot = input[(first + end)/2];
int i = first - 1;
int j = end + 1;
while (true) {
do {
i++;
} while (input[i] < pivot);
do {
j--;
} while (input[j] > pivot);
if (i < j)
swap(input, i, j);
else
return j;
}
}
public static void swap(int[] input, int i, int j){
int temp = input[i];
input[i] = input[j];
input[j] = temp;
}
public static int select(int[] input, int k){
return mySelect(input, 0, input.length-1, k);
}
public static int mySelect(int[] input, int left, int right, int k){
// If k is smaller than number of elements in array
if (k > 0 && k <= right - left + 1) {
int pos = partition(input, left, right);
if (pos - left == k - 1)
return input[pos];
// If position is larger, recursive call on the left subarray
if (pos - left > k - 1)
return mySelect(input, left, pos-1, k);
// if smaller, recursive call on the right subarray
return mySelect(input, pos+1, right, k-pos+left-1);
}
System.out.println("Invalid k value");
return Integer.MAX_VALUE;
}
public static void main(String[] args){
test2 = new int[]{99, 44, 77, 22, 55, 66, 11, 88, 33};
int[] test2 = new int[]{99, 44, 77, 22, 55, 66, 11, 88, 33};
//testing for selecting kth min
System.out.println("The 1st smallest : " + select(test2, 1));
System.out.println("The 2nd smallest : " + select(test2, 2));
System.out.println("The 3rd smallest : " + select(test2, 3));
System.out.println("The 4th smallest : " + select(test2, 4));
System.out.println("The 6th smallest : " + select(test2, 6));
System.out.println("The 9th smallest : " + select(test2, 9));
}
but my 1st smallest element appears 22, 2nd smallest returns 11, while others values are normal.
can someone please help me find what is the mistake I made?
The problem in your code is in the partition. The do while is the culprit here. You are updating the positions before checking the conditions and that's causing the problem with the last swap operation.
Update your method to this and you will be good to go
public static int partition(int[] input, int first, int end) {
int pivot = input[(first + end)/2];
int i = first;
int j = end;
while (true) {
while (input[i] < pivot) {
i++;
}
while (input[j] > pivot) {
j--;
}
if (i < j)
swap(input, i, j);
else
return j;
}
}
I wrote this code while I was learning quick sort. The mistake I made was in not realizing that
'left' and 'right' are indices in array whereas,
'pivot' is one of the values stored in array
You can study my code below and determine what's wrong in your understanding of the algorithm!!
public class QuickSort
{
public static void main(String[] args)
{
int[] nums = {1,5,9,2,7,8,4,2,5,8,9,12,35,21,34,22,1,45};
quickSort(0,nums.length-1,nums);
//print nums to see if sort is working as expected,omit printing in your case
print(nums);
//now you can write code to select kth smallest number from sorted nums here
}
/**
* left and right are indices in array whereas
* pivot is one of the values stored in array
*/
static int partition(int left, int right , int pivot, int[] nums)
{
int leftIndex = left -1;
int rightIndex = right;
int temp = 0;
while(true)
{
while( nums[++leftIndex] < pivot );
while( rightIndex>0 && nums[--rightIndex] > pivot );
if( leftIndex >= rightIndex ) break;
else//swap value at leftIndex and rightIndex
{
temp = nums[leftIndex];
nums[leftIndex]= nums[rightIndex];
nums[rightIndex] = temp;
}
}
//swap value at leftIndex and initial right index
temp = nums[leftIndex];
nums[leftIndex]= nums[right];
nums[right] = temp;
return leftIndex;
}
static void quickSort( int leftIndex , int rightIndex ,int[] nums)
{
if( rightIndex-leftIndex <= 0 ) return;
else
{
int pivot = nums[rightIndex];
int partitionIndex = partition(leftIndex, rightIndex , pivot,nums);
quickSort(leftIndex,partitionIndex-1,nums);
quickSort(partitionIndex+1,rightIndex,nums);
}
}
static void print(int[] nums)
{
for( int i = 0 ; i < nums.length ; i++ )
{
System.out.print(nums[i]+", ");
}
}
}

Returning the index of the n-th highest value of an unsorted list

I have written the following code and am now trying to figure out the best way to achieve what is explained in the four comments:
Integer[] expectedValues = new Integer[4];
for (int i = 0; i <= 3; i++) {
expectedValues[i] = getExpectedValue(i);
}
int choice = randomNumGenerator.nextInt(100) + 1;
if (choice <= intelligence) {
// return index of highest value in expectedValues
} else if (choice <= intelligence * 2) {
// return index of 2nd highest value in expectedValues
} else if (choice <= intelligence * 3) {
// return index of 3rd highest value in expectedValues
} else {
// return index of lowest value in expectedValues
}
What would be an elegant way o doing so? I do not need to keep expected values as an array - I am happy to use any data structure.
You could create a new array containing the indices and sort on the values - in semi-pseudo code it could look like this (to be adapted):
int[][] valueAndIndex = new int[n][2];
//fill array:
valueAndIndex[i][0] = i;
valueAndIndex[i][1] = expectedValues[i];
//sort on values in descending order
Arrays.sort(valueAndIndex, (a, b) -> Integer.compare(b[1], a[1]));
//find n-th index
int n = 3; //3rd largest number
int index = valueAndIndex[n - 1][0];
If you want to work with simple arrays, maybe this might be a solution:
public static void main(String[] args) {
int[] arr = new int[] { 1, 4, 2, 3 };
int[] sorted = sortedCopy(arr);
int choice = randomNumGenerator.nextInt(100) + 1;
if (choice <= intelligence) {
System.out.println(findIndex(arr, sorted[3])); // 1
} else if (choice <= intelligence * 2) {
System.out.println(findIndex(arr, sorted[2])); // 3
} else if (choice <= intelligence * 3) {
System.out.println(findIndex(arr, sorted[1])); // 2
} else {
System.out.println(findIndex(arr, sorted[0])); // 0
}
}
static int[] sortedCopy(int[] arr) {
int[] copy = new int[arr.length];
System.arraycopy(arr, 0, copy, 0, arr.length);
Arrays.sort(copy);
return copy;
}
static int findIndex(int[] arr, int val) {
int index = -1;
for (int i = 0; i < arr.length; ++i) {
if (arr[i] == val) {
index = i;
break;
}
}
return index;
}
You can "wipe out" the highest value n-1 times. After this the highest value is the n-th highest value of the original array:
public static void main(String[] args) {
int[] numbers = new int[]{5, 9, 1, 4};
int n = 2; // n-th index
for (int i = 0; i < n - 1; ++i) {
int maxIndex = findMaxIndex(numbers);
numbers[maxIndex] = Integer.MIN_VALUE;
}
int maxIndex = findMaxIndex(numbers);
System.out.println(maxIndex + " -> " + numbers[maxIndex]);
}
public static int findMaxIndex(int[] numbers) {
int maxIndex = 0;
for (int j = 1; j < numbers.length; ++j) {
if (numbers[j] > numbers[maxIndex]) {
maxIndex = j;
}
}
return maxIndex;
}
The complexity is O(n * numbers.length).

sorting using heapsort in java

import java.util.Arrays;
public class Test{
//main method
public static void main(String... args){
int[] a = new int[]{16,14,10,8,7,9,3,2,4,1};
System.out.println("unsorted array " + Arrays.toString(a));
heap_sort(a);
System.out.println("Sorted array " + Arrays.toString(a));
}
//returns left child index of given index
private static int left_child(int i){
return (i * 2 + 1);
}
//returns right child index of the given index
private static int right_child(int i){
return (i * 2 + 2);
}
public static void max_heapify(int[] array , int index , int heap_size){
int largest = index;
int left = left_child(index);
int right = right_child(index);
if(left < heap_size && array[left] > array[index]){
largest = left;
}
else largest = index;
if (right < heap_size && array[right] > array[largest]){
largest = right;
}
if(largest != index){
//exchange array[index] with array[largest]
int a = array[index];
array[index] = array[largest];
array[largest] = a;
max_heapify(array,largest,heap_size);
}
}
public static void build_max_heap(int[] array){
int heap_size = array.length - 1;
for (int i = ((array.length - 1) / 2) ; i >= 0 ; i--){
max_heapify(array, i, heap_size);
}
}
//main heap sort function
public static void heap_sort(int[] array){
int heap_size = array.length - 1;
build_max_heap(array);
for(int i = (array.length - 1) ; i > 0 ; i--){
//exchange array[0] with array[i]
int a = array[0];
array[0] = array[i];
array[i] = a;
heap_size = heap_size - 1;
max_heapify(array , 1 , heap_size);
}
}
}
I have tried almost every possibility but it doesn't works fine .Could u find out where i am wrong.
Output of my code is :
unsorted array [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
Sorted array [14, 10, 8, 7, 9, 3, 2, 4, 1, 16]
There are some problems:
- Left and right child are modified because you loose the first element in the array.
- In max_heapify function, the loops are <=
- In heap_sort function you must pass 0 instead of 1 to the max_heapify function.
//returns left child index of given index
private static int left_child(int i)
{
return (i * 2);
}
//returns right child index of the given index
private static int right_child(int i)
{
return (i * 2 + 1);
}
public static void max_heapify(int[] array, int index, int heap_size)
{
int largest = index;
int left = left_child(index);
int right = right_child(index);
if (left <= heap_size && array[left] > array[index])
{
largest = left;
}
if (right <= heap_size && array[right] > array[largest])
{
largest = right;
}
if (largest != index)
{
//exchange array[index] with array[largest]
int a = array[index];
array[index] = array[largest];
array[largest] = a;
max_heapify(array, largest, heap_size);
}
}
public static void build_max_heap(int[] array)
{
int heap_size = array.length - 1;
for (int i = ((array.length - 1) / 2); i >= 0; i--)
{
max_heapify(array, i, heap_size);
}
}
//main heap sort function
public static void heap_sort(int[] array)
{
int heap_size = array.Length - 1;
build_max_heap(array);
for (int i = (array.Length - 1); i > 0; i--)
{
//exchange array[0] with array[i]
int a = array[0];
array[0] = array[i];
array[i] = a;
heap_size = heap_size - 1;
max_heapify(array, 0, heap_size);
}
}
The problem is that you loose items because the left and right child must be:
//returns left child index of given index
private static int left_child(int i){
return (i * 2);
}
//returns right child index of the given index
private static int right_child(int i){
return (i * 2 + 1);
}

Stackoverflow Error while finding min and max in an array?

I am working on a problem to find Minimum and Maximum value in an array. I have my below program, whenever I run it, I am seeing java.lang.StackOverflowError:
public class MinMaxInArray {
public static void main(String[] args) {
int a1[] = { 3, 4, 2, 6, 8, 1, 9, 12, 15, 11 };
Pair result = getMinMax(a1, 0, a1.length - 1);
System.out.println("Min: " + result.min);
System.out.println("Max: " + result.max);
}
public static Pair getMinMax(int[] arr, int low, int high) {
Pair result = new Pair();
Pair left = new Pair();
Pair right = new Pair();
// if there is only one element arr= {1}
if (low == high) {
result.min = arr[low];
result.max = arr[high];
}
// if there are two element arr={1,2}
if (high == low + 1) {
if (arr[low] > arr[high]) {
result.max = arr[low];
result.min = arr[high];
} else {
result.max = arr[high];
result.min = arr[low];
}
return result;
}
// if there are more than 2 elements
int mid = (low + high) / 2;
left = getMinMax(arr, low, mid);
right = getMinMax(arr, mid + 1, high);
if (left.min < right.min) {
result.min = left.min;
} else {
result.min = right.min;
}
if (left.max > right.max) {
result.max = left.max;
} else {
result.max = right.max;
}
return result;
}
static class Pair {
int min;
int max;
}
}
Why this error is being thrown and what does it mean? How can I fix this?
You forgot the return result; in this piece of code:
// if there is only one element arr= {1}
if (low == high) {
result.min = arr[low];
result.max = arr[high];
return result;
}
I don't think recursion makes sense for this task. This code works well:
int a1[] = { 3, 4, 2, 6, 8, 1, 9, 12, 15, 11 };
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int a : a1) {
if (a < min) {
min = a;
}
if (a > max) {
max = a;
}
}
System.out.println("Min: " + min);
System.out.println("Max: " + max);
Unless you want to make it recursively, easiest solution is using a stream:
IntSummaryStatistics stats = Arrays.stream(a1).summaryStatistics();
int max = stats.getMax();
int min = stats.getMin();
// or:
int max = Arrays.stream(a1).max();
int min = Arrays.stream(a1).min();
Other way is using for-loop and simply checking every number:
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i : a1) {
if (i > max) {
max = i;
}
if (i < min) {
min = i;
}
}

Categories

Resources