Мое решение набрало 100% правильности, но 0% производительности. Я просто не могу понять, как минимизировать временную сложность.
Проблема:
Напишите функцию:
int solution(int A[], int N);
что для заданного массива из N положительных целых чисел возвращает максимальное количество конечных нулей числа, полученного путем умножения трех разных элементов из массива. Числа считаются разными, если они находятся на разных позициях в массиве.
Например, если A = [7, 15, 6, 20, 5, 10], функция должна вернуть 3 (вы можете получить три нуля в конце, взяв произведение чисел 15, 20 и 10 или 20, 5 и 10) .
В другом примере, если A = [25, 10, 25, 10, 32], функция должна вернуть 4 (вы можете получить четыре нуля в конце, взяв произведение чисел 25, 25 и 32).
Предположим, что:
- N — целое число в диапазоне [3..100 000];
- каждый элемент массива A является целым числом в диапазоне [1..1 000 000 000].
Сложность:
- ожидаемая временная сложность в наихудшем случае составляет O(N*log(max(A)));
- ожидаемая сложность пространства в наихудшем случае составляет O (N) (не считая памяти, необходимой для входных аргументов).
Решение:
идея:
- разложить каждый элемент на пары пятерок и двоек
- суммировать каждые 3 пары в одну пару - это стоит O(N^3)
- найти пару, у которой минимальное значение координаты самое большое
- вернуть это минимальное значение координаты
код:
int solution(int A[], int N) {
int fives = 0, twos = 0, max_zeros = 0;
int(*factors)[2] = calloc(N, sizeof(int[2])); //each item (x,y) represents the amount of 5's and 2's of the corresponding item in A
for (int i = 0; i< N; i++) {
factorize(A[i], &fives, &twos);
factors[i][0] = fives;
factors[i][1] = twos;
}
//O(N^3)
for (int i = 0; i<N; i++) {
for (int j = i + 1; j<N; j++) {
for (int k = j + 1; k<N; k++) {
int x = factors[i][0] + factors[j][0] + factors[k][0];
int y = factors[i][1] + factors[j][1] + factors[k][1];
max_zeros = max(max_zeros, min(x, y));
}
}
}
return max_zeros;
}
void factorize(int val, int* fives, int* twos) {
int tmp = val;
*fives = 0, *twos = 0;
if (val == 0) return;
while (val % 5 == 0) { //factors of 5
val /= 5;
(*fives)++;
}
while (val % 2 == 0) { //factors of 2
val /= 2;
(*twos)++;
}
}
Я не могу понять, как еще я могу перебирать массив размером N, чтобы найти оптимальные элементы 3 за время O(N*log(max(A))).