C 如何将计算有界切片数的时间复杂度降低到O(N)?

C 如何将计算有界切片数的时间复杂度降低到O(N)?,c,algorithm,time,complexity-theory,C,Algorithm,Time,Complexity Theory,给出了一个整数K和一个由N整数组成的非空零索引数组a。 一对整数(P,Q),使得0≤ P≤ Q

给出了一个整数
K
和一个由
N
整数组成的非空零索引数组
a
。 一对整数(P,Q),使得
0≤ P≤ Q
,称为数组a的一个切片

有界_切片是切片中最大值和最小值之间的差值小于或等于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];
        }
    }
}
int解决方案(int K,int A[],int N){
//用C90编写代码
int p,q,max,min,bndSlice=N;
对于(p=0;p<(N-1);p++){
对于(q=(p+1);q
如何将上述代码的时间复杂度降低到O(N)?

您的代码是O(N^3)。有一种更简单的方法使其
O(n^2*logn)

使用(RMQ)预处理数组,因此MaxMinSlice()需要O(1)来查询给定的最大值和最小值(p,q)的差


RMQ是O(n*logn)。那么总时间是O(n*logn)+O(n^2)

有界切片允许重叠吗?我怀疑在这种情况下是否有可能低于O(N^2)(假设所有数组元素都相等,这意味着每个可能的切片都有界,这意味着得到一组经过N^2的切片,这意味着O(N^2)的复杂性)

如果不允许有边界的_切片重叠:

设置p=Q=1。设置最小值=最大值=A[P]。增加Q,将min和max调整为[Q],直到(max-min)>K。然后,[P..Q-1]是有界切片。设置P=Q并从开始重复,直到达到N。这需要O(N)操作


如果允许有界切片重叠,则在上述算法中,在找到有界切片时,将p=p+1设置为p=Q。但是这需要O(N^2)操作。

编辑:解决方案是错误的(片应该重叠)

这是我的密码

/*给出了N、K和A[]的值*/
变量数\u的\u切片=0,当前\u最大\u界限=0,当前\u位置=0;
var当前_值=A[当前_位置];
var当前值\u最大值\u界限值;
while(当前\u最大\u界限
已在此处发布解决方案:


我在同一个问题上发布了一个O(N)答案,可能重复一些小的修正:对于(p=0;p/* 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);