Поиск массива с наименьшим максимальным значением элемента

У меня есть массив массивов int[], и я пытаюсь найти массив с наименьшим максимальным элементом.

Например, из массивов [1,2,5], [0,1,2], [8,0,0] это будет массив [0,1,2], поскольку максимальный элемент равен 2.

Однако мой код работает неправильно. Не могли бы вы помочь мне исправить мой код? Спасибо!

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
        }
    }
}

Какая ошибка? Что такое list? Пожалуйста, создайте минимальный воспроизводимый пример

GBlodgett 27.05.2019 15:33

Какой массив вы планируете вернуть, если два или более имеют одинаковое минимальное максимальное значение?

deHaar 27.05.2019 15:34

Извините, ошибки нет, застрял в цикле. Список — это массив массивов.

user11518299 27.05.2019 15:35

@deHaar Я хотел бы вернуть оба / несколько массивов, если это произойдет, но сначала я сосредоточусь на поиске только одного.

user11518299 27.05.2019 15:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
4
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Ваш код находит наименьшее значение во всех массивах (по крайней мере, если вы исправите опечатку от list.get(i)[i] до list.get(i)[j]).

Вы должны найти максимальный элемент каждого массива, а затем проверить, меньше ли этот максимум, чем все ранее найденные максимумы:

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
    }
}

Спасибо, однако я думаю, что мне придется переосмыслить свой подход, так как это очень медленно для объема моих данных. Я обязательно буду использовать ваше решение в своем переработанном подходе. Спасибо еще раз

user11518299 27.05.2019 15:38

@Джейн, в худшем случае вам нужно проверить все элементы всех массивов, но вы можете оптимизировать, выйдя из внутреннего цикла, как только max > min.

Eran 27.05.2019 15:40

Я использовал ваш код, просто удалил ArrayList, чтобы избавиться от вложенного цикла. Разница в минутах :). Спасибо

user11518299 27.05.2019 16:00

Вы можете попробовать это, например:

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);
    }
}

Я проверил это на вашем примере :):

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);
    }
}

В качестве альтернативы циклу for вы можете попытаться решить эту проблему с помощью потоковое API. Идея точно такая же:

  • найти максимальный элемент в каждом подсписке.
  • используйте компаратор, чтобы найти подсписок с минимальным элементом среди максимальных элементов.
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(); 

Кода меньше, возможно, легко понять назначение кода. Вы даже можете сделать код короче, используя метод Comparator::comparing:

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

Давайте посмотрим, что здесь происходит более подробно.

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]

Таким образом, выполнение может выглядеть примерно так:

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. 

Я надеюсь, что вы найдете это полезным.

Другие вопросы по теме