这个问题是在Codility上发现的一个练习题,这里可以找到一个链接示例。 https://codility.com/public-report-detail/
问题:我们有一个N个整数的数组 - 其中0 <= N&lt; 100,000 - 其中每个整数介于-2,8XX,XXX和+ 2,8XX之间,XXX(签名的int范围)。挑战在于找出是否存在点P,其中P之前的所有数组值的总和等于P之后的总和。
即。和(A [0]到A [P-1])==总和(A [P + 1]到A [N-1])
ex.
A[0] = -1
A[1] = 3
A[2] = -4
A[3] = 5
A[4] = 1
A[5] = -6
A[6] = 2
A[7] = 1
P = 1 is an equilibrium index of this array, because:
A[0] = −1 = A[2] + A[3] + A[4] + A[5] + A[6] + A[7]
P = 3 is an equilibrium index of this array, because:
A[0] + A[1] + A[2] = −2 = A[4] + A[5] + A[6] + A[7]
P = 7 is also an equilibrium index, because:
A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] = 0
在找到可接受的P的第一个实例后,程序可以退出。
完成挑战需要30分钟,显然预期的解决方案是O(N)。我可以想到一些问题的O(NlogN)解决方案 - 以及在一次删除一个值之前涉及数组求和的O(N)解决方案,但这不适用于极端情况,其中每个值都是2,8XX,XXX,XXX。
我在C ++工作,但即使是伪也会很棒。关于处理这种约束的正确算法的建议?
答案 0 :(得分:1)
如果可以使用64位整数,则可以使用的版本:计算数组的累积和,然后复制数组并从后面再次计算累积和。然后逐步执行两个累积和,并且给定索引处的值在两者中都相等,则得到P
例如,您的示例数组变为
-1 2 -2 3 4 -2 0 1
和
1 2 -1 3 -2 -3 3 1
* * *
其中P点标有星号。
如果你不能直接使用64位整数,那么我想我会为余数制作额外的数组,即用另一个有符号的int数组手动重新创建64位功能,并且在检查时要求两个数组匹配。我不认为在这种一般方法下你还可以做任何事情。