数组

时间:2017-11-06 19:38:04

标签: c++ algorithm

对于 N 整数数组,最多 K 将被取出(不更改元素的原始顺序)。函数 f 计算相邻元素之间的差异总和(当考虑到,对于给定的数字序列, f 的结果值将是 lastNumber - firstNumber ,因为其中的所有其他人都会被取消)。当从数组中取出 m< = K 数字的任意选择时,找出 f 可以具有的最大值(导致新的数组)

因为对于 f ,只有第一个和最后一个元素很重要,我的角度是覆盖这些“边界”移位的情况,对于给定的 m ,比较结果并采取最大的价值。如果我正确检查了代码,时间复杂度为 o(n ^ 2),但当我将其发送给评估时,响应为“超出时间限制”。有没有更好的方法解决这个问题,或者我错过了我的代码(我做了一些测试示例,输出是正确的,所以这是算法的问题,我相信)。

以下是代码:

#include <iostream>
#include <string>


using namespace std;

int main() {

    int N, K;
    int *arr;
    int max;

    cin >> N;

    arr = new int[N];

    //Some input constraints

    if (N < 2 || N > 500000) {
        fprintf(stderr, "Los input\n");
        exit(EXIT_FAILURE);
    }

    cin >> K;


    if (K < 0 || K > N - 2) {
        fprintf(stderr, "Los input\n");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < N; i++) {
        cin >> arr[i];
        if (arr[i] < -1000000 || arr[i] > 1000000) {
            fprintf(stderr, "Los input\n");
            exit(EXIT_FAILURE);
        }   
    }

    //The nested loop which checks boundary differences
    //depending on where the bounds are 

    max = arr[N-1] - arr[0];
    for (int i = 0; i <= K; i++) {

        for (int j = 0; j <= K - i; j++) {

            if ( max < arr[N-1-i] - arr[j])
                max = arr[N-1-i] - arr[j];
        }

    }


    cout << max << endl;
    delete [] arr;

    return 0;

}

编辑:我试图对彼得·德·里瓦兹(Peter de Rivaz)的线性复杂性方法进行一次尝试。我注意到我的代码中有重复的计算。所以我决定这样做:因为端点都很重要,所以我改变了外部循环,以便每次迭代时,我都会将“间隔”(缩短一个元素)移动到原始数组。

对于k = 1:长度为N-1的数组(原始中的2个拟合位置) 对于k = 2:长度为N-2(3拟合......)的数组

等等。令人惊讶的是,即使没有过多的操作,仍然会超出时间限制。

#include <iostream>
#include <string>


using namespace std;

int main() {

    int N, K;
    int *arr;
    int max;

    cin >> N;

    arr = new int[N];

    if (N < 2 || N > 500000) {
        fprintf(stderr, "Los input\n");
        exit(EXIT_FAILURE);
    }

    cin >> K;


    if (K < 0 || K > N - 2) {
        fprintf(stderr, "Los input\n");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < N; i++) {
        cin >> arr[i];
        if (arr[i] < -1000000 || arr[i] > 1000000) {
            fprintf(stderr, "Los input\n");
            exit(EXIT_FAILURE);
        }   
    }

    max = arr[N-1] - arr[0];

    for (int i = 1; i <= K; i++) {

        for (int j = 0; j <= i; j++) {

            if (max < arr[j+N-1-i] - arr[j]) 
                max = arr[j + N - 1 - i] - arr[j];

            cout << (arr[j + N - 1 - i] - arr[j]) << endl;

        }   

    }   
    cout << max << endl;
    delete [] arr;

    return 0;

}

1 个答案:

答案 0 :(得分:1)

如果你考虑lastNumber的一个特定值(通过从数组的右端删除x),那么我们将通过为firstNumber选择最小的可能值来获得最大的总数。

我们删除了x,因此我们可以从左侧删除多达K-x。因此,此x值的最佳值来自第一个K-x + 1条目中的最小值(这些是firstNumber的所有可能值)。

从等于K的x开始,按递减顺序工作。

减少顺序很有用,因为第一个K-x + 1条目的最小值可以用前一个最小值的O(1)额外工作来计算。

总的来说,这会导致O(n)复杂性。