对于 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;
}
答案 0 :(得分:1)
如果你考虑lastNumber的一个特定值(通过从数组的右端删除x),那么我们将通过为firstNumber选择最小的可能值来获得最大的总数。
我们删除了x,因此我们可以从左侧删除多达K-x。因此,此x值的最佳值来自第一个K-x + 1条目中的最小值(这些是firstNumber的所有可能值)。
从等于K的x开始,按递减顺序工作。
减少顺序很有用,因为第一个K-x + 1条目的最小值可以用前一个最小值的O(1)额外工作来计算。
总的来说,这会导致O(n)复杂性。