При допущении, что числа меньше одного не допускаются и нет дубликатов, для этого существует простое тождество суммирования - сумма чисел от 1
до m
с шагом 1
равна (m * (m + 1)) / 2
, Затем вы можете суммировать массив и использовать эту идентичность.
Вы можете узнать, есть ли дублирование по вышеуказанным гарантиям, плюс гарантия, что число не больше m или меньше n (что можно проверить в O(N)
)
Идея в псевдокоде:
0) Начните с N = 0
1) Возьмите N-й элемент в списке.
2) Если он не в нужном месте, если список был отсортирован, проверьте, где он должен быть.
3) Если место, где оно должно быть, уже имеет такой же номер, у вас есть дубликата - ВОЗВРАТ ИСТИНА
4) В противном случае поменяйте местами номера (чтобы поставить первое число в нужном месте).
5) С номером, который вы только что поменяли местами, он в нужном месте?
6) Если нет, вернитесь к шагу два.
7) В противном случае начните с первого шага с N = N + 1. Если это будет за концом списка, у вас не будет дупликов.
И, да, он работает в O(N)
, хотя может выглядеть как O(N ^ 2)
Примечание для всех (материал взят из комментариев)
Это решение работает в предположении, что вы можете изменить массив, а затем использовать сортировку Radix на месте (которая достигает скорости O(N)
).
Были предложены другие математические решения, но я не уверен, что какое-либо из них было доказано. Существует множество сумм, которые могут быть полезны, но большинство из них сталкиваются с увеличением числа битов, необходимых для представления суммы, что нарушит постоянную гарантию дополнительного пространства. Я также не знаю, способен ли какой-либо из них произвести различное число для данного набора чисел. Я думаю, что может сработать сумма квадратов, которая имеет известную формулу для ее вычисления (см. Wolfram's )
Новое понимание (ну, больше размышлений, которые не помогают решить его, но интересны, и я иду спать):
Итак, упомянуто, возможно, использование суммы + суммы квадратов. Никто не знал, сработало ли это или нет, и я понял, что это становится проблемой только тогда, когда (x + y) = (n + m), как, например, факт 2 + 2 = 1 + 3. Квадраты также имеют эту проблему благодаря Пифагорейские тройки (поэтому 3 ^ 2 + 4 ^ 2 + 25 ^ 2 == 5 ^ 2 + 7 ^ 2 + 24 ^ 2, а сумма квадратов не работает). Если мы используем последнюю теорему Ферма , мы знаем, что это не может произойти при n ^ 3. Но мы также не знаем, существует ли x + y + z = n для этого (если мы не знаем, и я этого не знаю). Так что никаких гарантий, что это тоже не сломается - и если мы продолжим этот путь, у нас быстро кончатся биты.
Однако в своем восторге я забыл заметить, что вы можете разбить сумму квадратов, но при этом вы создадите нормальную сумму, которая недопустима. Я не думаю, что вы можете сделать и то и другое, но, как уже было отмечено, у нас нет доказательств в любом случае.
Должен сказать, что найти контрпримеры иногда намного проще, чем доказать! Рассмотрим следующие последовательности, каждая из которых имеет сумму 28 и сумму квадратов 140:
[1, 2, 3, 4, 5, 6, 7]
[1, 1, 4, 5, 5, 6, 6]
[2, 2, 3, 3, 4, 7, 7]
Я не смог найти таких примеров длины 6 или меньше. Если вы хотите, чтобы пример имел правильные значения min и max, попробуйте этот пример длиной 8:
[1, 3, 3, 4, 4, 5, 8, 8]
Более простой подход (изменение идеи Хаззена):
Целочисленный массив длины m содержит все числа от n до n + m-1 ровно один раз, если
- каждый элемент массива находится между n и n + m-1
- дубликатов нет
(Причина: в данном целочисленном диапазоне есть только m значений, поэтому, если массив содержит m уникальных значений в этом диапазоне, он должен содержать каждое из них один раз)
Если вам разрешено изменять массив, вы можете проверить оба за один проход по списку с помощью модифицированной версии идеи алгоритма Хаззена (нет необходимости выполнять суммирование):
- Для всех индексов массива от 0 до m-1 сделать
- Если массив [i] = n + m => RETURN FALSE («найдено значение вне диапазона»)
- Рассчитать j = массив [i] - n (это позиция массива [i] на основе 0 в отсортированном массиве со значениями от n до n + m-1)
- Хотя j не равно i
- Если list [i] равен list [j] => RETURN FALSE («найден дубликат»)
- Обмен списками [i] со списком [j]
- Пересчитать j = массив [i] - n
- ВОЗВРАТ ИСТИНА
Я не уверен, считается ли модификация исходного массива максимально допустимым дополнительным пространством O (1), но если этого не произойдет, это должно быть решением, которое хотел оригинальный плакат.