How to add two integers represented by two arrays efficiently, putting the solution into another array

Eduardo :

Time ago, I was asked during an interview to sum two Integers represented by arrays, putting the solution into another array. Part of the interview idea was for me to provide an efficient solution. Since then, I have been searching for a simple and efficient solution to this problem, and I didn't find none yet.

So I would like to share my solution with the community and ask if any of you can help to improve efficiency. This example looks like O(mn) where mn is the size of the biggest array between m or n and, where m and n represents the size of each integer array to sum. Thus, it looks as though it is working in linear time.

public class ArrayRudiments {

    /**
     * Add two integers represented by two arrays
     * 
     * NOTE: Integer as a natural number, not as a programming language data type.
     * Thus, the integer can be as big as the array permits.
     * 
     * @param m first number as array
     * @param n second number as array
     * @return integer sum solution as array
     */
    public Integer[] sum(Integer m[], Integer n[]) {
        int carry = 0, csum = 0;
        final Vector<Integer> solution = new Vector<Integer>();

        for (int msize = m.length - 1, nsize = n.length - 1; msize >= 0 || nsize >= 0; msize--, nsize--) {

            csum = (msize < 0 ? 0 : m[msize]) + (nsize < 0 ? 0 : n[nsize]) + carry;
            carry = csum / 10;

            solution.insertElementAt(csum % 10, 0);
        }

        if (carry > 0) {
            solution.insertElementAt(carry, 0);
        }

        return solution.toArray(new Integer[] {});
    }

}

The problem or trick here is that the not linear time job is carried out by the Vector class inserting new elements and resizing the solution array. This way, the solution is not working in linear time. Is it possible to create a similar solution without Vector class?

You can also see a working tested version of this code in https://github.com/lalounam/rudiments

Sweeper :

As SSP has said in the comments, you should create an ArrayList with an initial capacity, of Math.max(m.length, n.length) + 1. That is the maximum number of digits of the sum.

int arrayCapacity = Math.max(m.length, n.length) + 1;
final List<Integer> solution = new ArrayList<>(arrayCapacity);

Then you need to fill this with 0s:

for (int i = 0 ; i < arrayCapacity ; i++) {
    solution.add(0);
}

Here's the "trick". In the main for loop, you don't fill the array from the start, you fill it from the end. Instead of insertElementAt the start, you set the element at whatever index we are iterating at, plus 1, because solution is one longer than the longer of m and n.

solution.set(Math.max(msize, nsize) + 1, csum % 10);

This is essentially filling the list "from the back".

And at the end you resize the list like this:

if (carry > 0) {
    solution.set(0, carry);
    return solution.toArray(new Integer[] {});
} else {
    return solution.subList(1, solution.size()).toArray(new Integer[] {});
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=327542&siteId=1