给出一个由 N 个整数组成的非空零索引数组 A。一对整数 (P, Q) 满足 0 ≤ P < Q < N,称为数组 A 的切片(注意该切片至少包含两个元素)。切片 (P, Q) 的平均值是 A[P] + A[P + 1] + … + A[Q] 除以切片长度的总和。准确地说,平均值等于 (A[P] + A[P + 1] + … + A[Q]) / (Q − P + 1)。
例如,数组 A 使得:
A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8
包含以下示例切片:
- 切片 (1, 2),其平均值为 (2 + 2) / 2 = 2;
- 切片 (3, 4),其平均值为 (5 + 1) / 2 = 3;
- 切片 (1, 4),其平均值为 (2 + 2 + 5 + 1) / 4 = 2.5。
目标是找到平均值最小的切片的起始位置。
写一个函数:
class Solution { public int solution(int[] A); }
即,给定一个由 N 个整数组成的非空零索引数组 A,返回具有最小平均值的切片的起始位置。如果有多个切片具有最小平均值,则应返回此类切片的最小起始位置。
例如,给定数组 A 使得:
A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8
如上所述,该函数应返回 1。
假使,假设:
- N为[2..100,000]范围内的整数;
- 数组 A 的每个元素都是 [−10,000..10,000] 范围内的整数。
复杂:
- 预期的最坏情况时间复杂度为 O(N);
- 预期的最坏情况空间复杂度为 O(N),超出输入存储(不包括输入参数所需的存储)。
可以修改输入数组的元素。
这是我最好的解决方案,但在时间复杂度方面显然不是最优的。
有任何想法吗?
public int solution(int[] A) {
int result = 0;
int N = A.length;
int [] prefix = new int [N+1];
for (int i = 1; i < prefix.length; i++) {
prefix[i] = prefix[i-1] + A[i-1];
}
double avg = Double.MAX_VALUE;
for (int i = 1; i < N; i++) {
for (int j = i+1; j <=N; j++) {
double temp = (double)(prefix[j]-prefix[i-1]) /(double)(j-i+1);
if (temp < avg) {
avg = temp;
result = i-1;
}
}
}
return result;
}
https://codility.com/demo/results/demo65RNV5-T36/
原文由 Jose P. 发布,翻译遵循 CC BY-SA 4.0 许可协议
我几天前发布了这个:
但我刚刚看到它被版主删除了。他们说链接已失效,但我刚刚试过了,它工作正常。我再次发布它,希望可以验证链接是否良好。
现在我还可以根据我之前提供的代码链接提供我的实现: https ://codility.com/demo/results/demoERJ4NR-ETT/