让left(k)
表示数组中值的总和,从A[0]
到A[k]
。证明是微不足道的:
left(k+1)=left(k)+A[k+1]
如果您已经计算left
了给定的 for k
,那么left
fork+1
是通过将下一个元素添加到 来计算的left
。
换句话说:
如果您遍历数组,从元素 #0 到元素 #n-1(其中n
是数组的大小),您left
只需将数组中的下一个元素添加到left
.
这似乎是显而易见的和不言而喻的,但它有助于正式说明这一点,以便该过程的下一步变得同样明显。
以同样的方式,给定right(k)
表示数组中从元素 #k 开始直到数组中最后一个元素的值的总和,您还可以证明以下内容:
right(k+1)=right(k)-A[k]
因此,您可以通过从数组中所有值的总和 as和as开始,找到和k
之间的最小差异(我使用的符号与您的问题使用的符号略有不同,因为我的符号更方便) ,然后然后, computing继续从头到尾迭代数组,在运行中计算这两个和每一步,并计算左值和右值之间的差异。找到差异最小的地方变得微不足道。left(k)
right(k+1)
right(0)
A[0]
left(0)
right(1)
left
right
我想不出任何其他方法来做到这一点,不到O(n)
:
1) 计算数组中所有值的总和,初始值为right(0)
O(n)。
2) 右边的迭代当然是 O(n)。
我不相信对数二进制搜索在这里会起作用,因为值abs(left(k)-right(k))
本身不会按排序顺序排列。
顺便说一句,使用这种方法,您还可以在数组也包含负值时找到最小差异。唯一的区别是,由于差异不再是抛物线,您只需遍历整个数组,并跟踪abs(left-right)
最小的位置。