Reputation: 2072
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.
Upvotes: 2
Views: 2386
Reputation: 493
public int min(){
int a[] ={2,5,1,3};
int min, secondMin = a[0];
for(int i=0;i<a.length;i++){
if(min>a[i]){
secondMin =min;
min= a[i];
}
}
return secondMin;
}
i got the second min from above code segment...try this.....
Upvotes: 0
Reputation: 44446
There is a way even without sorting working in the case all the numbers are unique. Filter out the minimum value and ask again for another one resulting in the 2nd lowest value.
int firstMin = Arrays.stream(arr).min().getAsInt();
int secondMin = Arrays.stream(arr).filter(i -> i != firstMin).min().getAsInt();
System.out.println(firstMin); // prints 2
System.out.println(secondMin); // prints 3
Edit: There is another way using the TreeSet
implementation which stores already sorted values. Remove the lowest one and ask for the first element again - it results in the 2nd lowest element:
SortedSet<Integer> sortedSet = Arrays.stream(arr)
.boxed()
.collect(Collectors
.toCollection(TreeSet::new));
sortedSet.remove(sortedSet.first());
int secondMin = sortedSet.first();
System.out.println(secondMin); // prints 3
Upvotes: 3
Reputation: 444
EDIT: As mentioned in comments - below solution will NOT work for parallel processing!
To avoid sorting we can use reduce
function. And reduce to "pair like structure" (in the example imitated by array):
public class Test {
private static final int SECOND_LOWEST = 1;
private static final int LOWEST = 0;
@Test
public void test() {
Integer[] arr = {0, 3, 4, 5, 2, 3, 5, 6, 7, 8, 1};
List<Integer> list = Arrays.asList(arr);
int[] identity = {Integer.MAX_VALUE, Integer.MAX_VALUE};
int[] result = list.stream()
.reduce(identity, (acc, elem) -> calculate(acc, elem), (acc1, acc2) -> acc1);
System.out.println(Arrays.toString(result));
}
private int[] calculate(int[] acc, Integer elem) {
if (acc[LOWEST] > elem) {
int prevLowest = acc[LOWEST];
acc[LOWEST] = elem;
acc[SECOND_LOWEST] = prevLowest;
} else if (acc[SECOND_LOWEST] > elem) {
acc[SECOND_LOWEST] = elem;
}
return acc;
}
Upvotes: 0
Reputation: 4555
Using an IntStream
, you can easily sort it and skip the first element:
public int findSecondMin(int[] arr)
{
return IntStream.of(arr).sorted().skip(1).findFirst().orElse(Integer.MAX_VALUE);
}
But of course, you don't have to use streams. java.util.Arrays
has a nice sort method, and then you can just take the second element:
public int findSecondMin(int[] arr)
{
Arrays.sort(arr);
return arr.length < 2 ? Integer.MAX_VALUE : arr[1];
}
To avoid sorting the whole array, we can take your approach and adapt it into a custom reduction on the stream:
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];
}
Compared to a for loop based implementation, it might be harder to read, but can work in parallel.
Upvotes: 4
Reputation: 558
here you find the Example
List<Integer> numbers = Arrays.asList(10, 2, 3, 4, 5, 6);
numbers.sort(Comparator.naturalOrder());
System.out.println(numbers.get(1));
Upvotes: 0