最小切片位置 - 订单N算法

时间:2015-07-30 21:17:28

标签: algorithm

给出了由N个整数组成的非空零索引数组A.一对整数(P,Q),使得0≤P<1。 Q&lt; N,称为阵列A的切片 (注意切片包含至少两个元素)。切片(P,Q)的平均值是A [P] + A [P + 1] + ... + A [Q]之和除以 切片的长度。确切地说,平均值等于(A [P] + A [P + 1] + ... + A [Q])/(Q - P + 1)。

写一个函数:

int solution(int A [],int N);

给定由N个整数组成的非空零索引数组A,返回具有最小平均值的切片的起始位置。 如果有多个切片具有最小平均值,则应返回此切片的最小起始位置。

假设:

N是[2..100,000]范围内的整数; 数组A的每个元素都是[-10,000..10,000]范围内的整数。 复杂度:

预期的最坏情况时间复杂度为O(N); 预期的最坏情况空间复杂度是O(N),超出输入存储(不计算输入参数所需的存储空间)。

您是否只能发布订单N的解决方案?

3 个答案:

答案 0 :(得分:1)

如果A只有正数,你就可以侥幸成功:

pos = 0
min_avg = A[0] + A[1]
for (i=2; i<N; i++)
    m = A[i-1] + A[i]
    if (m < min_avg)
        min_avg = m
        pos = i-1
return pos

这仅取两个数字的平均值,因为较大的切片的平均值不能小于较小切片的最小值。

如果A有负数,您可以先调高所有值:

offset = min(A)
for (i=0; i<N; i++)
    A[i] -= offset

结合以前的算法:

offset = min(A) * 2              (because we're adding two numbers below)
pos = 0
min_avg = A[0] + A[1] - offset
for (i=2; i<N; i++)
    m = A[i-1] + A[i] - offset
    if (m < min_avg)
        min_avg = m
        pos = i-1
return pos

答案 1 :(得分:0)

我认为你是对的,我能做的最好的是O(N 2 )解决方案(这是在Python中):

x

然而,较大切片的平均值倾向于原始范围的平均值(中间值)。在这种情况下,平均值为零,介于-10000和10000之间。大多数情况下,最小平均值是两个值的切片,但有时它可以是三个值的切片,很少可以是更多的值。所以我认为我以前的答案适用于大多数(> 90%)的案例。这实际上取决于数据值。

答案 2 :(得分:-1)

    #include <assert.h>
    struct Slice { unsigned P, Q; };
    struct Slice MinSlice( int A[], unsigned N ) {
        assert( N>=2 );
        // find min slice of length 2
        unsigned P = 0;
        double min_sum = A[P] + A[P+1];
        for (unsigned i = 1; i < N-1; ++i)
            if ( min_sum > A[i] +A[i+1] ) {
                P = i;
                min_sum = A[P] + A[P+1];
            }
        unsigned Q = P+1;
        double min_avg = min_sum / 2;
        //extend the min slice if the avg can be reduced.
        //(in the direction that most reduces the avg)
        for (;;) {
            if ( P > 0 && ( Q >= N-1 || A[P-1] <= A[Q+1] ) ) {
                //reducing P might give the best reduction in avg
                double new_sum = A[P-1] + min_sum;
                double new_avg = new_sum / (Q - P + 2);
                if ( min_avg < new_avg )
                    break;
                min_sum = new_sum; 
                min_avg = new_avg; 
                --P;
             } else if ( Q < N-1 && ( P <= 0 || A[P-1] >= A[Q+1] ) ) {
                //increasing Q might give the best reduction in avg
                double new_sum = min_sum + A[Q+1];
                double new_avg = new_sum / (Q - P + 2);
                if ( min_avg < new_avg )
                    break;
                min_sum = new_sum; 
                min_avg = new_avg; 
                ++Q;
             } else
                 break;
        }
        struct Slice slice = { .P = P, .Q= Q };
        return slice;
    }