考虑我有一个非空的整数数组:A0..An
。并考虑参数P where 0 < P <=n
。我需要找到由P分割的左右子阵列之间的最小绝对差值。例如:
A[0] = 3
A[1] = 1
A[2] = 2
A[3] = 4
A[4] = 3
P = 1, difference = |3 − 10| = 7
P = 2, difference = |4 − 9| = 5
P = 3, difference = |6 − 7| = 1
P = 4, difference = |10 − 3| = 7
本案例中的解决方案是1
我完成了以下代码:
def solution(A):
lsum, rsum = A[0], sum(A[1:])
diff = abs(rsum - lsum)
p = 1
while True:
lsum += A[p]
rsum -= A[p]
next = abs(rsum - lsum)
if next < diff:
diff = next
p += 1
else:
return diff
但我的解决方案有一些错误。它在某些情况下有效但在某些情况下会返回错误的答案。例如:在large sequence, numbers from -1 to 1, length = ~100,000
之类的条件下,它会返回错误的答案
P.S。:我完成了以下解决方案:
def solution(lst):
lsum, rsum = lst[0], sum(lst[1:])
diff = abs(lsum - rsum)
for i in xrange(1, len(lst) - 1):
lsum += lst[i]
rsum -= lst[i]
ndiff = abs(lsum - rsum)
diff = min(diff, ndiff)
return diff
答案 0 :(得分:5)
这更简洁但仍然是O(n):
import itertools
def min_diff(A):
total = sum(A)
return min(abs(total - lsum - lsum) for lsum in itertools.accumulate(A))
itertools.accumulate
可从Python 3.2开始。
答案 1 :(得分:3)
错误是这样的:
if next < diff:
diff = next
p += 1
else:
return diff
如果next
上的diff
没有改善,您就会终止。这是错误的,因为您以后仍可能找到更好的解决方案。
除此之外,我认为你的想法是朝着正确的方向发展的。你应该做些什么来修复你的bug无条件地遍历整个数组,最后只返回diff
。
像这样:
def solution(A):
lsum, rsum = A[0], sum(A[1:])
diff = abs(rsum - lsum)
p = 1
while p < (len(A)-1):
lsum += A[p]
rsum -= A[p]
next = abs(rsum - lsum)
if next < diff:
diff = next
p += 1
return diff
(注意:我尝试尽可能少地修改,即保持尽可能接近你的代码。另外,我没有真正测试过这个。但我希望你能得到这个想法。)
答案 2 :(得分:0)
这是你的翻拍,但摆脱列表上的索引
并使用min
内置函数来获得最小值。
def solution(a):
lsum = a[0]
rsum = sum(a)-lsum
dfs = [abs(rsum-lsum),]
for el in a[1:]:
lsum+=el
rsum-=el
dfs.append(abs(rsum-lsum))
return min(dfs)
用
调用它sol = solution([3,1,2,4,3])
print(sol)
产生
1