我正在阅读“编程珍珠”一书,并被困在某个地方。 该问题的(最佳)原始解决方案(查找具有最大总和的子数组)是:
maxsofar = О
maxendinghere = О
for i = [0. n)
{
maxendinghere = max(maxendinghere + x[i], 0)
maxsofar = max(maxsofar, maxendinghere)
}
然后问题改变如下,并要求修改程序:
我们必须找到最接近零(不最小值)或其他数字 f 的
这个解决方案在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) ;
}
感谢。
答案 0 :(得分:4)
反例:[30; -50; 45]
首先,您将选择30
。然后,当你到达-50时,maxendinghere
将是-20
而maxsofar
也是-20
。当您到达45
时,您将maxendinghere = closest(-20 + 45 = 25, 30) = 25
,maxsofar
将保持-20
。
但正确的答案是-5
:-50 + 45 = -5
答案 1 :(得分:1)
这是一个反例。
[100, 2, -2, -50]
正确的答案是子数组[2, -2]
。但是,由于100 + 2 - 2 == 100
,100 + 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]
。