如何减少计算有界切片数到O(N)的时间复杂度?

时间:2014-01-23 12:53:02

标签: c algorithm time complexity-theory

给出整数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)?

4 个答案:

答案 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);