给出整数K
和由A
整数组成的非空零索引数组N
。
一对整数(P,Q),如0 ≤ P ≤ Q < N
,称为数组A的切片。
bounded_slice是一个切片,其中切片中最大值和最小值之间的差值小于或等于K.更准确地说,它是一个切片,例如max(A[P], A[P + 1], ..., A[Q]) − min(A[P], A[P + 1], ..., A[Q]) ≤ K
。
目标是计算有界参数的数量。
我的解决方案如下:
int solution(int K, int A[], int N){
// write your code in C90
int p, q, max, min, bndSlice = N;
for(p = 0; p < (N - 1); p++){
for(q = (p + 1); q < N; q++){
MaxMinSlice(A, p, q, &max, &min);
if((max - min) <= K){
bndSlice++;
}
if(bndSlice > 1000000000){
return 1000000000;
}
}
}
return bndSlice;
}
void MaxMinSlice(int A[], int p, int q, int *max, int *min){
int i;
*max = *min = A[p];
for(i = p; i <= q; i++){
if(*max < A[i]){
*max = A[i];
}
if(*min > A[i]){
*min = A[i];
}
}
}
如何将上述代码的时间复杂度降低到O(N)?
答案 0 :(得分:1)
答案 1 :(得分:0)
您的代码是O(n ^ 3)。有一种更简单的方法可以使它成为O(n^2 * log n)
。
使用Range Minimum Query(RMQ)预处理数组,以便MaxMinSlice()需要O(1)来查询给定(p,q)的最大值和最小值之差。
RMQ是O(n * logn)。所以总时间是O(n * log n)+ O(n ^ 2)
答案 2 :(得分:0)
bounds_slices是否允许重叠?我怀疑在这种情况下可能低于O(N ^ 2)(假设所有数组元素的平凡情况相等,这意味着每个可能的切片都是有界的,这意味着你得到一组经过N ^ 2的切片,这表明O(N ^ 2)复杂度。
如果不允许bounded_slices重叠:
设置P = Q = 1。设定min = max = A [P]。增加Q,将min和max调整为A [Q],直到(max-min)> K.然后,[P..Q-1]是有界切片。设置P = Q并从开始重复,直到达到N.这需要O(N)操作。
如果允许有界切片重叠,则在上述算法中,当找到有界切片时,设置P = P + 1而不是P = Q.但这需要O(N ^ 2)次操作。
答案 3 :(得分:0)
编辑:解决方案是错误的(切片应该重叠)
此代码位于jsfiddle
/* values N, K and A[] are given */
var number_of_slices = 0, current_max_bound = 0, current_position = 0;
var current_value = A[current_position];
var current_max_bound_value;
while (current_max_bound < N) {
current_max_bound_value = A[current_max_bound];
if ( Math.abs(current_max_bound_value - current_value) < K ) {
current_max_bound = current_max_bound + 1;
} else {
number_of_slices = number_of_slices + 1;
current_max_bound = current_max_bound + 1;
current_position = current_max_bound;
current_value = A[current_position];
}
}
console.log('result: ' + number_of_slices);