3

I was asked in an interview to rewrite this method without the nested for-loop. All I knew apart from this was that the arrays are of the same size. What's a good way to approach this ?

public int addTwo(int[] first, int[] second) {
    int result = 0;
    for (int k : first) {
        for (int i : second) {
            result += k * i;
        }
    }
    return result;
}

1 Answers1

5

If we remeber Matematics, if in first array we have k1, k2, k3, in second array we have i1,i2,i3, so result k1 * i1 + k1 * i2 + k1 * i3 + k2 * i1 + ...

So we can see, we should refactoring this math expression like k1 * (i1 + i2 + i3) + k2 * (i1 + i2 + i3) + k3 * (i1 + i2 + i3)

And k1 * (i1 + i2 + i3) + k2 * (i1 + i2 + i3) + k3 * (i1 + i2 + i3) = (k1 + k2 + k3) * (i1 + i2 + i3).

So you can refactoring your code as

public int addTwo(int[] first, int[] second) {
    int firstSum = 0;
    int secondSum = 0;

    for (int k : first) {
        firstSum += k;            
    }

    for (int i : second) {
        secondSum += i;
    }

    return firstSum * secondSum;
}
Slava Vedenin
  • 58,326
  • 13
  • 40
  • 59
  • 2
    And `k1 * (i1 + i2 + i3) + k2 * (i1 + i2 + i3) + k3 * (i1 + i2 + i3)` = `(k1 + k2 + k3) * (i1 + i2 + i3)` so both multiplication loops can be eliminated. – Klitos Kyriacou Mar 02 '21 at 21:36
  • 1
    If the arrays are of the same length, as the OP states, then the two sums can be calculated inside the same for loop. I guess it was also what the interviewer expected to hear. – lainatnavi Mar 02 '21 at 21:43
  • @lainatnavi yes, that's true, but it may be inefficient on modern processors. Having two separate loops, each one fetching data from consecutive memory addresses, would make best use of the CPU cache line. Fetching alternately from two different addresses could make the CPU spend longer time fetching the data. – Klitos Kyriacou Mar 03 '21 at 10:47