Minimum subarray difference in python

浪尽此生 提交于 2021-02-11 13:28:55

问题


Consider I have a non-empty array of integers: A0..An. And consider a parameter P where 0 < P <=n. I need to find a minimum absolute difference between left and right subarray splited by P. For example:

  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

The solution in this case is 1

I finished with the code below:

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

but I my solution has some bugs. It works in some cases but return wrong answer in some conditions. For example: in condition like large sequence, numbers from -1 to 1, length = ~100,000 it returns the wrong answer

P.S.: I finished with solution below:

 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

回答1:


The bug is this:

if next < diff:
    diff = next
    p += 1
else:
    return diff

You terminate if next is not improving on diff. This is wrong, since you still might find a better solution later on.

Other than that, I think your idea goes in the right direction. What you should do to fix your bug is go through the whole array unconditionally and just return diffin the end. Like so:

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

(Note: I tried to modify as little as possible, i.e. to stay as close to your code as possible. Also, I did not really test this. But I hope you get the idea.)




回答2:


This is more concise yet still 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 is available from Python 3.2 up.




回答3:


EDIT (the previous solution had a high complexity, my bad)

This is a remake of yours, but getting rid of the indexing on the list and using the min built-in function to get the minimum.

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)

calling it with

sol = solution([3,1,2,4,3])
print(sol)

produces

1


来源:https://stackoverflow.com/questions/33276923/minimum-subarray-difference-in-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!