C ++ - 最大化数组及其索引中两个元素的总和

时间:2016-06-26 23:56:12

标签: c++ algorithm

如何在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);
    }
}

2 个答案:

答案 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 -> maxL: Tab[K]+K -> max然后K<=L。换句话说,如果LK分别是两个最大值的索引,则属性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,问题中的代码也不会。