让left(k)表示数组中值的总和,从A[0]到A[k]。证明是微不足道的:
left(k+1)=left(k)+A[k+1]
如果您已经计算left了给定的 for k,那么leftfork+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)leftright
我想不出任何其他方法来做到这一点,不到O(n):
1) 计算数组中所有值的总和,初始值为right(0)O(n)。
2) 右边的迭代当然是 O(n)。
我不相信对数二进制搜索在这里会起作用,因为值abs(left(k)-right(k))本身不会按排序顺序排列。
顺便说一句,使用这种方法,您还可以在数组也包含负值时找到最小差异。唯一的区别是,由于差异不再是抛物线,您只需遍历整个数组,并跟踪abs(left-right)最小的位置。