如何在O(N)中解决以下编程之谜?
整数数组:
Tab[N]
查找max(Tab[K] - K + Tab[L] + L)
其中0 <= K <= L <= N
我能提出的唯一解决方案是O(N^2)
,我会比较每个元素并更新最大总和。
int curr_max = INTEGER_MIN;
for(int i = 0; i < N; i++){
for(int j = i; j < N; j++){
curr_max = max(Tab[i]-i + Tab[j] + j,curr_max);
}
}
答案 0 :(得分:3)
通常,由于K<=L
约束,解决此类任务的一种可能方法是使用预先计算的运行最大值。 (以下版本可以进行优化,但无论如何都有O(N)
时间和空间复杂度。)
int t[N+1]; // input
int a[N+1]; // running max t[i]-i, left to right
a[0] = t[0]-0;
for (int i = 1; i <= N; ++i)
a[i] = max(a[i-1], t[i]-i);
int b[N+1]; // running max t[i]+i, right to left
b[N] = t[N]+N;
for (int i = N-1; i >= 0; --i)
b[i] = max(b[i+1], t[i]+i);
int mx = a[0] + b[0];
for (int i = 1; i <= N; ++i)
mx = max(mx, a[i] + b[i]);
但是,在我们的案例中,可以显示K: Tab[K]-K -> max
和L: Tab[K]+K -> max
然后K<=L
。换句话说,如果L
和K
分别是两个最大值的索引,则属性L<=K
成立。因此,天真的方法也应该起作用:
int K = 0, L = 0;
for (int i = 1; i <= N; ++i) {
if (t[i]-i > t[K]-K)
K = i;
if (t[i]+i > t[L]+L)
L = i;
}
assert(K <= L);
int mx = t[K]-K + t[L]+L;
答案 1 :(得分:0)
怎么样:
int L_max = INTEGER_MIN;
int K_max = INTEGER_MIN;
for(int i=0; i<N; i++)
{
K_max = max(Tab[i] -i, K_max);
L_max = max(Tab[i] +i, L_max);
}
curr_max = K_max + L_max;
请注意,它不会验证K&lt; = L,问题中的代码也不会。