Codility Training: Java Solution to TapeEquilibrium



A non-empty zero-indexed array A consisting of N integers is given. Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two non-empty parts: A[0], A[1], ..., A[P − 1] and A[P], A[P + 1], ..., A[N − 1].
The difference between the two parts is the value of: |(A[0] + A[1] + ... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
In other words, it is the absolute difference between the sum of the first part and the sum of the second part.
Write a function:
class Solution { public int solution(int[] A); }
that, given a non-empty zero-indexed array A of N integers, returns the minimal difference that can be achieved.
Complexity:
  • expected worst-case time complexity is O(N);
  • expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
The Solution
The idea is simple: first scan the array to get its sum, then scan again to compute the difference between first part and second part.

We can use add accumulatively to get the sum from a[0] to a[i], to get the difference: diff = Math.abs(2 * prefixSum - sum);

/**
 * O(1) space
 */
public int solution(int[] A) {
  if (A == null)
    throw new IllegalArgumentException("Can't be null");
  if (A.length == 0) {
    return 0;
  }
  if (A.length == 1) {
    return Math.abs(A[0]);
  }

  int sum = 0;
  for (int i = 0; i < A.length; i++) {
    sum += A[i];
  }
  int minRst = Integer.MAX_VALUE;

  // ignore last one, as second array can't be empty
  int prefixSum = 0;
  for (int i = 0; i < A.length - 1; i++) {
    prefixSum += A[i];
    int diff = Math.abs(2 * prefixSum - sum);
    if (diff < minRst) {
      minRst = diff;
    }
  }

  return minRst;
}
This is my first solution, it takes O(n) extra space.
/**
 * O(n) space
 */
public int solution1(int[] A) {
  if (A == null)
    throw new IllegalArgumentException("Can't be null");
  if (A.length == 0) {
    return 0;
  }
  if (A.length == 1) {
    return Math.abs(A[0]);
  }

  int[] prefixSum = new int[A.length];

  prefixSum[0] = A[0];
  for (int i = 1; i < A.length; i++) {
    prefixSum[i] += prefixSum[i - 1] + A[i];
  }
  int sum = prefixSum[A.length - 1];
  int minRst = Integer.MAX_VALUE;

  // ignore last one, as second array can't be empty
  for (int i = 0; i < A.length - 1; i++) {
    int diff = Math.abs(2 * prefixSum[i] - sum);
    if (diff < minRst) {
      minRst = diff;
    }
  }

  return minRst;
}

Test Code
To take a real interview test in codility, it's important to add more test cases and run them in our own IDE before submit the solution.

public static void main(String[] args) {
  TapeEquilibrium instance = new TapeEquilibrium();

  Map<int[], Integer> inAns = new HashMap<int[], Integer>();
  // the input and answer from the origin question
  inAns.put(new int[] { 3, 1, 2, 4, 3 }, 1);

  inAns.put(new int[] { 1 }, 1);
  inAns.put(new int[] { 1, 3 }, 2);
  inAns.put(new int[] { 3, 1 }, 2);
  inAns.put(new int[] { -1 }, 1);
  inAns.put(new int[] { 1, -1 }, -1);

  for (Entry<int[], Integer> entry : inAns.entrySet()) {
    assertEquals(instance.solution(entry.getKey()), entry.getValue()
        .intValue());
  }
 }

Lesson Learned
Notice common bug pattern: < or <=, init value is 0 or 1, A.length - 1 or A.length etc.
Handle and test edge cases.
Analyze time and space complexity, and whether we can improve it.

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)