Ben said:
puzzlecracker said:
Given an array of size n,
and its populated with consecutive integers
from 1
to n, i.e. [1, 2...n-1, n] in random order.
Two integers are removed,
meaning zero is placed in their places.
Give O (n) efficient algorithm
to find them WITHOUT using extra space?
I expect that any solution would require at least O(1) extra
space.
/* BEGIN extra_space.c */
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 20
#define FIRST_ZERO 3
#define SECOND_ZERO 17
#define LU_RAND(S) ((S) * 69069 + 362437)
#define LU_RAND_SEED 123456789LU
void all_different(long unsigned *array, long unsigned n,
long unsigned seed);
void place_zeros(long unsigned *array, long unsigned n,
long unsigned first, long unsigned second);
void find_numbers(long unsigned *array, long unsigned n,
long unsigned *number, long unsigned *scratch);
int main(void)
{
long unsigned *array, *extra_space, n, number[2];
array = malloc(ARRAY_SIZE * sizeof *array);
if (array == NULL) {
fputs("malloc failure_1\n", stderr);
exit(EXIT_FAILURE);
}
extra_space = malloc(ARRAY_SIZE * sizeof *extra_space);
if (extra_space == NULL) {
fputs("malloc failure_2\n", stderr);
exit(EXIT_FAILURE);
}
all_different(array, ARRAY_SIZE, LU_RAND_SEED);
place_zeros(array, ARRAY_SIZE, FIRST_ZERO, SECOND_ZERO);
find_numbers(array, ARRAY_SIZE, number, extra_space);
free(extra_space);
for (n = 0; n != ARRAY_SIZE; ++n) {
printf("%lu\n", array[n]);
}
free(array);
printf("\n%lu %lu\n", number[0], number[1]);
return 0;
}
void find_numbers(long unsigned *array, long unsigned n,
long unsigned *number, long unsigned *scratch)
{
long unsigned count, index;
for (count = 0; count != n; ++count) {
scratch[count] = 0;
}
for (count = 0; count != n; ++count) {
if (array[count] != 0) {
scratch[array[count] - 1] = array[count];
}
}
for (index = count = 0; count != n; ++count) {
if (scratch[count] == 0) {
number[index++] = count + 1;
if (index == 2) {
break;
}
}
}
}
void place_zeros(long unsigned *array, long unsigned n,
long unsigned first, long unsigned second)
{
while (n-- != 0) {
if (array[n] == first || array[n] == second) {
array[n] = 0;
}
}
}
void all_different(long unsigned *array,
long unsigned n, long unsigned seed)
{
long unsigned i, r;
array[0] = 1;
for (i = 1; n > i; ++i) {
seed = LU_RAND(seed);
r = seed % (i + 1);
array
= 0;
array = array[r];
array[r] = i + 1;
}
}
/* END extra_space.c */