编程珍珠:查找具有最大总和的子阵列

时间:2010-09-21 19:13:21

标签: arrays algorithm

我正在阅读“编程珍珠”一书,并被困在某个地方。 该问题的(最佳)原始解决方案(查找具有最大总和的子数组)是:

maxsofar = О 
maxendinghere = О 
for i = [0. n) 
{
   maxendinghere = max(maxendinghere + x[i], 0) 
   maxsofar = max(maxsofar, maxendinghere) 
}

然后问题改变如下,并要求修改程序:

我们必须找到最接近零(最小值)或其他数字 f

  1. 所以我只需将函数“ max ”更改为某个函数来解决这个问题,该函数将返回接近零(或f)的数字。
  2. maxsofar将初始化为最接近零(或f)的元素
  3. 这个解决方案在O(n)中运行,但是作者提供的解决方案很难并且在O(nlogn)中运行并且声称这是最佳解决方案(理论上最好的解决方案)。

    请指出我的解决方案中的错误(如果书中说nlogn是最好的,那么我的解决方案必定会有一些错误。)

    更新: 所以我的答案是:

    closest = get_element_closest_to_zero(); 
    maxsofar = closest;
    maxendinghere = 0; 
    for i = [0. n) 
    {
       maxendinghere = closest_to_zero(maxendinghere + x[i], closest);
       maxsofar = closest_to_zero(maxsofar, maxendinghere) ;
    }
    

    感谢。

4 个答案:

答案 0 :(得分:4)

反例:[30; -50; 45]

首先,您将选择30。然后,当你到达-50时,maxendinghere将是-20maxsofar也是-20。当您到达45时,您将maxendinghere = closest(-20 + 45 = 25, 30) = 25maxsofar将保持-20

但正确的答案是-5-50 + 45 = -5

答案 1 :(得分:1)

这是一个反例。

[100, 2, -2, -50]

正确的答案是子数组[2, -2]。但是,由于100 + 2 - 2 == 100100 + 2 - 2 - 50 = 50和50更接近0,您的算法将返回[100, 2, -2, -50]

答案 2 :(得分:0)

序列[100, -201, 100]怎么样?这将给出初始条件

closest = 100
maxsofar = 100
maxendinghere = 0

一步后

x[i] = 100
maxendinghere = closest_to_zero(100, 100)
maxsofar = 100

经过两个步骤

x[i] = -201
maxendinghere = closest_to_zero(-101, 100)
maxsofar = 100

经过3个步骤

x[i] = 100
maxendinghere = closest_to_zero(-101, 100)
maxsofar = 100

答案 3 :(得分:0)

[1, 100, -100]

对于此数组,您的算法将返回[1],但正确的响应应为[100, -100]