Вот еще одно решение, использующее Collectors.groupingBy
из Java 8:
public static int singleNumber(int[] nums) {
return Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
Идея такова:
- группировка по номеру вхождения
- затем найдите тот, который повторяется только один раз
Примечание. Я предполагаю, что ваш массив содержит хотя бы один элемент, иначе вы можете проверить длину перед поиском, а затем выдать исключение, например:
public static int singleNumber(int[] nums) throws IllegalArgumentException{
if(nums.length == 0){
throw new IllegalArgumentException("empty array");
}
return Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
Еще глубже, если вы хотите избежать ситуации, когда несколько раз повторяются только один раз, вы можете использовать:
public static int singleNumber(int[] nums) throws IllegalArgumentException {
if (nums.length == 0) {
throw new IllegalArgumentException("empty array");
}
Map<Integer, Long> grouping = Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()));
if (grouping.values().stream().filter(c -> c == 1).count() > 1) {
throw new IllegalArgumentException("more than one element is repeated one time");
}
return grouping.entrySet().stream()
.filter(e -> e.getValue() == 1).findFirst().get().getKey();
}