Поскольку данные состоят из целых чисел, существует конечное число уникальных значений, которые могут возникать между любыми двумя значениями. Итак, начните с рассмотрения первого и последнего значения в массиве. Если a[length-1] - a[0] < length - 1
, будут некоторые повторяющиеся значения. Поместите a[0]
и a[length-1]
в контейнер с постоянным доступом, как хэш-набор. Если два значения равны, вы знаете, что в массиве есть только одно уникальное значение, и вы закончили. Вы знаете, что массив отсортирован. Итак, если два значения отличаются друг от друга, вы можете посмотреть на средний элемент. Если средний элемент уже находится в наборе значений, вы знаете, что можете пропустить всю левую часть массива и рекурсивно анализировать правую часть. В противном случае проанализируйте левую и правую части рекурсивно.
В зависимости от данных в массиве вы сможете получить набор всех уникальных значений в другом количестве операций. Вы получаете их в постоянное время O(1)
, если все значения совпадают, так как вы будете знать это после проверки только первого и последнего элементов. Если «относительно мало» уникальных значений, ваша сложность будет близка к O(log N)
, потому что после каждого раздела вы «довольно часто» сможете выбросить хотя бы половину анализируемого подматрица. Если значения уникальны и a[length-1] - a[0] = length - 1
, вы также можете «определить» набор в постоянное время, поскольку они должны быть последовательными числами от a[0]
до a[length-1]
. Однако, чтобы фактически перечислить их, вам нужно будет вывести каждое число, и их будет N.
Возможно, кто-то может предоставить более формальный анализ, но моя оценка заключается в том, что этот алгоритм примерно линейный по количеству уникальных значений, а не по размеру массива. Это означает, что, если существует несколько уникальных значений, вы можете получить их в нескольких операциях даже для огромного массива (например, в постоянное время, независимо от размера массива, если есть только одно уникальное значение). Поскольку число уникальных значений не больше, чем размер массива, я утверждаю, что это делает этот алгоритм «лучше, чем O (N)» (или, строго: «не хуже, чем O (N) и, во многих случаях, лучше»).
Вы должны знать последний элемент, так что вам не придется проходить по крайней мере все элементы один раз. Таким образом, минимальная граница O (N) –
Выход из цикла, если новый «уникальный» номер совпадает с номером последнего индекса. Поэтому, если вы достигнете первого '3', вы можете остановить цикл. – Tom
@Tom Было бы все равно O (N) –