Чтобы преодолеть требование, которое исключает любое дополнительное потребление памяти, опубликованный алгоритм изменяет значения внутри массива, просто отрицая их значение, но это оставило бы индекс 0 без изменений.
Я предлагаю другое сопоставление: из[0, размер) до ( -1 - размер , -1 ], так что, например, {0, 1, 2, 3, 4, ...} становится {-1, -2, -3, -4, -5, ...}. Обратите внимание, что для представления целых чисел в виде дополнения до двух, INT_MIN = -INT_MAX - 1.
// The following assumes that every value inside the array is in [0, size-1)
int missingVal(int* a, int size) // OT: I find the name misleading
{
int i = 0;
for (; i < size; i++)
{
int *pos = a[i] < 0
? a + (-a[i] - 1) // A value can already have been changed...
: a + a[i];
if ( *pos < 0 ) // but if the pointed one is negative, there's a duplicate
break;
*pos = -1 - *pos;
}
return i == size; // Returns 1 if there are no duplicates
}
При необходимости, оригиналзначения могут быть восстановлены перед возвратом с помощью простого цикла
if ( i != size ) {
for (int j = 0; j < size; ++j) {
if ( a[j] < 0 )
a[j] = -a[j] - 1;
}
} else { // I already know that ALL the values are changed
for (int j = 0; j < size; ++j)
a[j] = -a[j] - 1;
}