Во-первых, ваш подход - это то, что я бы назвал "грубой силой", и это действительно O (n ^ 2) в худшем случае. Это также неправильно реализовано, так как числа, которые повторяются n раз, считаются n-1 раз.
Если оставить в стороне, существует несколько способов решения проблемы. Первое (что предложили несколько ответов) - это итерация массива и использование карты для отслеживания того, сколько раз данный элемент был просмотрен. Предполагая, что карта использует хеш-таблицу для основного хранилища, сложность в среднем случае должна быть O (n), так как значения для получения и вставки с карты должны быть в среднем O (1), и вам нужно только выполнить итерации по списку и карте один раз каждый. Обратите внимание, что в худшем случае это все равно O (n ^ 2), поскольку нет гарантии, что хеширование даст результаты с постоянным временем.
Другой подход заключается в том, чтобы сначала просто отсортировать массив, а затем выполнить итерацию отсортированного массива в поисках дубликатов. Этот подход полностью зависит от выбранного метода сортировки и может быть в любом месте от O (n ^ 2) (для наивной сортировки пузырьков) до O (n log n), наихудшего случая (для сортировки слиянием) до O (n log n). ) средний, хотя и вероятный случай (для быстрой сортировки.)
Это лучшее, что вы можете сделать с подходом сортировки, предполагающим произвольные объекты в массиве. Так как в вашем примере используются целые числа, вы можете добиться гораздо большего успеха, используя радикальную сортировку, которая будет иметь сложность O (dn) в худшем случае, где d по существу постоянна (поскольку для 32-разрядных целых чисел она достигает максимума 9).
Наконец, если вы знаете, что элементы являются целыми числами и что их величина не слишком велика, вы можете улучшить решение на основе карты, используя массив размера ElementMax, который гарантировал бы O (n) наихудший случай сложность, с компромиссом, требующим 4 * дополнительных байта памяти ElementMax.