Вот кое-что, что работает для 1..N, вы можете просто использовать форумные арифметические ряды, чтобы приспособиться к этому [i, i + n]
// gcc -Wall q1.cc -o q1 && q1
//Given an array of size N in which every number is between 1 and N, write a simple program to determine
//if there are any duplicates in it.
//answer
/* The numbers can be assumed to not be stored in sorted order. We also assume that all numbers are
between 1 and N inclusive. If for example they are not, then we will return true indicating that there
is a possibility of a duplicate.
This can be implemented using a bit array of size N all initialized to 0. as we iterate the input array
of numbers, we simply check if the bit array at that number index is set, if so, we return true. if not
we set the bit. we loop until we get to the end of the list, and if we get there, that means no
duplicate was found, and we can return false.
However, the above algorithm has the problem of using extra space. A better idea is to take advantage
of the fact that we are guaranteed that the numbers are between 1 and N. if we were to use the fact
that the arithmetic sum of these numbers is equal to n(n+1)/2, then we can just sum up all the numbers
and ensure that it equals the above sum. If it does, we have no duplicate, else we do.
*/
#include <stdio.h>
#include <assert.h>
bool any_dup(const int *a, int n)
{
int req_sum = n*(n+1)/2;
int s = 0;
for (int i = 0;i<n;i++)
s += a[i];
return (s != req_sum);
}
int main()
{
int a[]={1,2,3,4,5};
assert(!any_dup(a,5));
int b[]={1,2,2,3,3,4,5,6};
assert(any_dup(b,8));
int c[]={5,2,3,1,4};
assert(!any_dup(c,5));
int d[]={34,21,1,4,2};
assert(any_dup(d,5));
return 0;
}