【发布时间】:2018-11-30 19:08:05
【问题描述】:
我的解决方案的正确性为 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)(不包括输入参数所需的存储空间)。
解决方案:
想法:
- 将每个元素分解为 5 和 2 对
- 将 每个 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 大小的数组,以便在 O(N*log(max(A))) 时间内找到最佳的 3 项。
【问题讨论】:
-
嗨,这个问题可能更适合Code review,因为它确实有效,但需要改进算法。
标签: c algorithm performance time-complexity