Sharing an answer code of mine about MinAbsSumOfTwo problem of Codility lesson 15.

Lesson 15: MinAbsSumOfTwo

Let A be a non-empty zero-indexed array consisting of N integers.

The abs sum of two for a pair of indices \((P, Q)\) is the absolute value \(\mid A[P] + A[Q]\mid\), for \(0 ≤ P ≤ Q < N\).

For example, the following array A:

\[A[0] = 1\\ A[1] = 4\\ A[2] = -3\]

has pairs of indices (0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2).
The abs sum of two for the pair (0, 0) is A[0] + A[0] = |1 + 1| = 2.
The abs sum of two for the pair (0, 1) is A[0] + A[1] = |1 + 4| = 5.
The abs sum of two for the pair (0, 2) is A[0] + A[2] = |1 + (−3)| = 2.
The abs sum of two for the pair (1, 1) is A[1] + A[1] = |4 + 4| = 8.
The abs sum of two for the pair (1, 2) is A[1] + A[2] = |4 + (−3)| = 1.
The abs sum of two for the pair (2, 2) is A[2] + A[2] = |(−3) + (−3)| = 6.

Write a function:

def solution(A)

that, given a non-empty zero-indexed array A consisting of N integers, returns the minimal abs sum of two for any pair of indices in this array.

For example, given the following array A:

\[A[0] = 1\\ A[1] = 4\\ A[2] = -3\]

the function should return 1, as explained above.

Given array A:

\[A[0] = -8\\ A[1] = 4\\ A[2] = 5\\ A[3] =-10\\ A[4] = 3\]

the function should return \(\mid (−8) + 5\mid = 3\).

Assume that:

  • N is an integer within the range [1..100,000];
  • each element of array A is an integer within the range [−1,000,000,000..1,000,000,000].

Complexity:

  • expected worst-case time complexity is O(N*log(N));
  • expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).

Answer Code in Python 3

  • Time complexity: \(O(N\log(N))\)
  • Space complexity: \(O(N)\)
# Python 3.6, Time complexity: O(nlog(n))
def solution(A):
    # Exception for only one element in the list A
    if len(A) == 1:
        return abs(A[0]+A[0])
    
    A.sort() # Sort the list
    
    # Seperate list A into two lists
    #   1. minus: list with minus sign integers
    #   2. plus: list with plus sign integers and zero
    minus, plus = [], []
    for i in range(len(A)):
        if A[i]<0:
            minus.append(A[i])
        else:
            plus.append(A[i])
    minus.reverse()
    
    # Exceptions
    if len(minus) == 0: # there is no minus sign
        return A[0]+A[0]
    if len(plus) == 0: # there is no plus sign
        return abs(A[-1]+A[-1])
        
    min_ = min(abs(minus[0]+minus[0]), plus[0]+plus[0]) # Initial min_
    right = 0
    # Compare plus and minus lists
    for i in range(len(plus)):
        while right < len(minus):
            if right-1 < 0 and right+1 < len(minus):
                right += 1
                continue
            elif abs(plus[i]+minus[right-1])>=abs(plus[i]+minus[right]) and right+1 < len(minus):
                right += 1
            else: # Stop when the min for 'i' is found
                right -= 1
                break
            
        # Check if it is min for until now
        if min_ > abs(plus[i]+minus[right]):
            min_ = abs(plus[i]+minus[right])
                
    return min_