Как найти дубликат в большом массиве кроме вложенного цикла?

Нужен способ кроме вложенного цикла так как в массиве более 10000 чисел и вложенным циклом будет слишком сильно жрать производительность


Ответы (1 шт):

Автор решения: Nowhere Man

Если нужно найти все дубликаты в исходном массиве, проще всего использовать какую-либо из реализаций Set (HashSet / LinkedHashSet):

static Set<Integer> findDups(int ... arr) {
    Set<Integer> ones = new HashSet<>();
    Set<Integer> dups = new LinkedHashSet<>(); // для сохранения порядка вставки
    for (int n : arr) {
        if (!ones.add(n)) {
            dups.add(n);
        }
    }
    return dups;
}

System.out.println(findDups(1, 2, 3, 5, 3, 7, 2, 1));
// -> [3, 2, 1]

Также можно вычислить частоту вхождения каждого числа, используя Map<Integer, Long>, и отфильтровав элементы мапы по частоте большей 1. Пример ниже использует Stream API:

static Set<Integer> findDupsMap(int ... arr) {
    return Arrays.stream(arr)
        .boxed()
        .collect(Collectors.groupingBy(
            n -> n,
            LinkedHashMap::new,
            Collectors.counting()
        ))
        .entrySet()
        .stream()
        .filter(e -> e.getValue() > 1)
        .map(Map.Entry::getKey)
        .collect(Collectors.toSet()); // порядок не гарантирован в HashSet
}

System.out.println(findDupsMap(1, 2, 3, 5, 3, 7, 2, 1));
// -> [1, 2, 3]
→ Ссылка