Если вам разрешено сортировать исходный массив, я считаю, что вы можете сделать это за время O (n lg U) и пространство O (lg U), где U - максимальный элемент массива.Идея заключается в следующем: используя радикальную сортировку MSD на месте , отсортируйте массив по времени O (n lg U) и O (lg U).Затем выполните итерацию по всему массиву.Поскольку все равные значения являются последовательными, вы можете подсчитать, сколько раз появляется каждое значение.Как только вы найдете значение, которое появляется четное количество раз, вы можете вывести ответ.Для этого второго сканирования требуется время O (n) и пространство O (1).
Если мы предположим, что U является фиксированной константой, это дает алгоритм O (n) -времени O (1) -пространства.Если вы этого не предполагаете, то использование памяти все еще лучше, чем алгоритм O (n), при условии, что lg U = O (n), что должно быть верно на большинстве машин.Кроме того, использование пространства только логарифмически столь же велико как самый большой элемент, означая, что практическое использование пространства довольно хорошо.Например, на 64-битной машине нам понадобится только место, достаточное для хранения 64 рекурсивных вызовов.Это намного лучше, чем выделять гигантский массив заранее.Более того, это означает, что алгоритм является алгоритмом со слабым полиномиальным временем как функция от U.
Тем не менее, это переставляет исходный массив и, таким образом, деструктивно модифицирует входные данные.В некотором смысле, это обман, потому что он использует сам массив для хранения O (n).
Надеюсь, это поможет!