首页 > 解决方案 > Find second min element from array

问题描述

Anyone can convert this in the Java functional style (lambda):

public int findSecondMin(int arr[]) {

    int min = Integer.MAX_VALUE, secondMin = Integer.MAX_VALUE;
    for (int i = 0; i < arr.length; i++) {
        if (min > arr[i]) {
            secondMin = min;
            min = arr[i];
        } else if (secondMin > arr[i]) {
            secondMin = arr[i];
        }
    }
    return secondMin;
}

I tried by applying the filter over this but it is not working.

标签: javaarrayslambdajava-8java-stream

解决方案


使用IntStream,您可以轻松对其进行排序并跳过第一个元素:

public int findSecondMin(int[] arr)
{
    return IntStream.of(arr).sorted().skip(1).findFirst().orElse(Integer.MAX_VALUE);
}

但是,当然,您不必使用流。java.util.Arrays有一个不错的排序方法,然后你可以只取第二个元素:

public int findSecondMin(int[] arr)
{
    Arrays.sort(arr);
    return arr.length < 2 ? Integer.MAX_VALUE : arr[1];
}

为避免对整个数组进行排序,我们可以采用您的方法并将其调整为流上的自定义归约:

public int findSecondMin(int[] arr)
{
    return IntStream.of(arr).boxed().reduce(
        new int[] {Integer.MAX_VALUE, Integer.MAX_VALUE},
        (mins, i) -> {
            return new int[] {Math.min(i, mins[0]), Math.min(Math.max(i, mins[0]), mins[1])};
        }, (mins1, mins2) -> {
            int[] lesser = mins1[0] < mins2[0] ? mins1 : mins2;
            int[] larger = mins1[0] < mins2[0] ? mins2 : mins1;
            return new int[] {lesser[0], Math.min(lesser[1], larger[0])};
        }
    )[1];
}

与基于 for 循环的实现相比,它可能更难阅读,但可以并行工作。


推荐阅读