Все значения положительные, поэтому мы можем использовать битовый знак для наших целей.
Итерация по массиву;для каждого элемента проверьте, является ли он отрицательным, если это так, отмените его и вычтите 1. Если он находится за пределами допустимого диапазона [0, N-1], конечно, входной массив недействителен, хотя вы говорите, что нам не нужно беспокоиться оэтот.
Если он находится в диапазоне, используйте его как индекс в самом массиве;если найденное вами значение положительное, сделайте его отрицательным и вычтите 1. Если оно отрицательное, это означает, что есть дублирующий элемент (вы уже поменяли его местами).
(«вычитать 1» нужно учитыватьдля 0, который остается тем же самым при отрицании)
Из-за принципа голубиного отверстия, если вы доберетесь до последнего элемента без дубликатов и без выходных значений, входной массив содержит все и только элементы в диапазоне[0, N-1].Если вам не нравится оставлять массив отрицательным, вы можете сделать последний проход, чтобы перевернуть знак каждого числа.
bool check(int *arr, int N) {
bool ret = true;
for(int i = 0; i < N && ret; ++i) {
int v = arr[i];
if(v < 0) v = -v - 1;
if(v >= N || arr[v] < 0) ret = false;
else arr[v] = -arr[v] - 1;
}
for(int i = 0; i < N; ++i) {
if(arr[i] < 0) arr[i] = -arr[i] - 1;
}
return ret;
}