Этот алгоритм представляет собой O (1) пространство (с некоторыми мошенничествами), O (n) время (среднее), требует, чтобы исходный массив был неконстантным и уничтожал его в конце. Также это ограничивает возможные значения в массиве (три бита каждого значения должны быть зарезервированы для алгоритма).
Половина ответа уже в вопросе. Используйте hashmap. Если число ударяется дважды, используйте разность индексов, обновите лучший на данный момент результат и удалите это число из хэш-карты, чтобы освободить место. Чтобы сделать это O (1) пробел, просто используйте исходный массив. Преобразовать массив в hashmap на месте.
Прежде чем превратить элемент массива в ячейку hashmap, запомните его значение и позицию. После этого он может быть безопасно перезаписан. Затем используйте это значение, чтобы вычислить новую позицию в хэш-карте и перезаписать ее. Элементы перемешиваются таким образом, пока не будет найдена пустая ячейка. Для продолжения выберите любой элемент, который еще не переупорядочен. Когда все переупорядочено, каждая пара int определенно ударяется дважды, здесь у нас есть пустая хэш-карта и обновленное значение наилучшего результата.
Один зарезервированный бит используется при преобразовании элементов массива в ячейки hashmap. В начале это очищается. Когда значение переупорядочивается в ячейке hashmap, этот бит устанавливается. Если этот бит не установлен для перезаписанного элемента, этот элемент просто используется для последующей обработки. Если этот бит установлен для перезаписи элемента, здесь возникает конфликт, выберите первый неиспользуемый элемент (этот бит не установлен) и замените его вместо этого.
Еще 2 зарезервированных бита используются для объединения конфликтующих значений. Они кодируют позиции, где начинается / заканчивается / продолжается цепь. (Может быть возможно оптимизировать этот алгоритм так, чтобы потребовалось только 2 зарезервированных бита ...)
Ячейка хэш-карты должна содержать эти 3 зарезервированных бита, индекс исходного значения и некоторую информацию для уникальной идентификации этого элемента. Чтобы сделать это возможным, хеш-функция должна быть обратимой, чтобы часть значения могла быть восстановлена, учитывая ее положение в таблице. В простейшем случае хеш-функция - это всего лишь ceil(log(n))
младший бит. Значение в таблице состоит из 3 полей:
3
зарезервированные биты
32 - 3 - (ceil(log(n)))
старшие биты от исходного значения
ceil(log(n))
бит для позиции элемента в исходном массиве
Сложность по времени O (n) только в среднем; в худшем случае сложность O (n ^ 2).
Другим вариантом этого алгоритма является последовательное преобразование массива в hashmap: на каждом шаге m
, имеющее 2^m
первых элементов массива, преобразованных в hashmap. Некоторые массивы постоянного размера могут чередоваться с хэш-картой, чтобы повысить производительность при низком m
. Когда значение m
высокое, должно быть достаточно пар int, которые уже обработаны и больше не нуждаются в пространстве.