2

I have an arraylist of int[] arrays and I'm trying to find the array with the lowest max element.

For an example, from arrays [1,2,5], [0,1,2], [8,0,0] it would be the array [0,1,2] because the max element is 2.

However, my code is not working correctly. Could you help me fix my code? Thanks!

int min = Integer.MAX_VALUE;
for (int i=0; i<list.size(); i++) {
    for (int j=0; j<list.get(i).length; j++) {
        if (list.get(i)[j]<min) {
            min = list.get(i)[i]; 
            minIndex = i; //index of the array in arraylist
        }
    }
}
4
  • 2
    What error? What is list? Please create a minimal reproducible example Commented May 27, 2019 at 13:33
  • What array are you planning to return if two or more have the same lowest maximum value? Commented May 27, 2019 at 13:34
  • Sorry, there is no error, it's stuck in a loop. List is the arraylist of arrays. Commented May 27, 2019 at 13:35
  • @deHaar I would like to return both/more arrays if that happens, but I am first focusing of finding just one. Commented May 27, 2019 at 13:36

3 Answers 3

2

Your code finds the lowest value across all arrays (at least it would if you fix the typo of list.get(i)[i] to list.get(i)[j]).

You should find the maximum element of each array, and then check if that maximum is smaller than all the previously found maximums:

int minIndex = 0;
int min = Integer.MAX_VALUE;
for (int i=0; i<list.size(); i++) {
    int max = Integer.MIN_VALUE;
    for (int j=0; j<list.get(i).length; j++) { // find max element of current array
        if (list.get(i)[j] > max) {
            max = list.get(i)[j]; 
            if (max > min) {
                break; // we already know the max of this array is not the smallest max
            }
        }
    }
    if (max < min) { // check if the max of the current array is the smallest max so far
        min = max;
        minIndex = i; //index of the array in arraylist
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, however I think I will have to rethink my approach, as this is extremely slow for the amount of my data. I will definitely use your solution in my reworked approach. Thanks again
@Jane at the worst case you have to test all elements of all arrays, but you can optimize by breaking from the inner loop once max > min.
I used your code, just removed the ArrayList to get rid of nested loop. The difference is minutes :). Thanks
0

You can try this for example:

import java.util.Arrays;
import java.util.Comparator;

public class MaxMinArray {

    public static int[]  maxMinFromArray(int[][] arrays){
       return  Arrays.stream(arrays).min(Comparator.comparingInt(x -> Arrays.stream(x).max().orElse(0))).orElse(null);
    }
}

I've tested it with your example :) :

import org.junit.Test;

import static org.junit.Assert.*;

public class MaxMinArrayTest {

    @Test
    public void testMaxMinArray(){
        int[][] arrays = new int[][] {{1,2,5}, {0,1,2}, {8,0,0}};
        int[] result = MaxMinArray.maxMinFromArray(arrays);
        assertArrayEquals(new int[]{0,1,2}, result);
    }
}

Comments

0

As an alternative to the for-loop you might try to resolve this issue using stream api. The idea is exactly the same:

  • find maximum element in each sublist.
  • use Comparator to find sublist with minimum element among maximum elements.
List.of(List.of(1, 2, 5), List.of(0, 1, 2), List.of(8, 0, 0)) 
        .stream()
        .min((a, b) ->  
               a.stream().max(Integer::compare).get()
                 .compareTo(
                    b.stream().max(Integer::compare).get()
                 )
        ).get(); 

There is less code it is arguably easily to understand the intention of the code. You can even make code shorter by using Comparator::comparing method:

List.of(List.of(1, 2, 5), List.of(0, 1, 2), List.of(8, 0, 0))
        .stream()
        .min(Comparator.comparing(Collections::max))
        .get();

Let's have a look at what is going on here in more details.

List.of(List.of(1, 2, 5), List.of(0, 1, 2), List.of(8, 0, 0))
        // lets get stream of list Stream<List<Integer>>. 
        .stream()
        // find sublist which has minimum maximum element. 
        .min((a, b) ->  
               // a & b are sublist, for example: [1,2,5], [0,1,2]
               // find maximum from a [1,2,5] which is [5]
               a.stream().max(Integer::compare).get()
               // compare maximum from a to maximum from b 
                 .compareTo(
                 // find maximum from a [0,1,2] which is [2]
                    b.stream().max(Integer::compare).get()
                 )
               // get minimum out of [5,2]
        ).get(); // [0, 1, 2]

So the execution might look similar to this:

Initial list is: [1,2,5], [0,1,2], [8, 0, 0]
find minimum list based on maximum: 
min( max([1,2,5]), max([0,1,2])) 
min( [5], [2]) 
[2] -> list [0,1,2] contains minimum maximum element so far, go the the next iteration
find minimum list based on maximum: 
min( max([0,1,2]), max([8, 0, 0]) ) 
min( [2], [8]) 
[2] -> list [0,1,2] contains minimum maximum element so far, 
there no other element in the stream, [0,1,2] is final result. 

I hope you find this useful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.