-2

Here is one task, i was trying to solve. You must write the function

void merge(ArrayList a, ArrayList b)  {
// code
}

The function recieves two ArrayLists with equal size as input parameters [a1, a2, ..., an], [b1, b2, ..., bn]. The execution result is the 1st ArrayList must contain elements of both lists, and they alternate consistently ([a1, b1, a2, b2, ..., an, bn]) Please read the bold text twice =)

Code must work as efficiently as possible.

Here is my solution

public static void merge(ArrayList a, ArrayList b) {
ArrayList result = new ArrayList();
int i = 0;

Iterator iter1 = a.iterator();
Iterator iter2 = b.iterator();
while ((iter1.hasNext() || iter2.hasNext()) && i < (a.size() + b.size())) {
    if (i % 2 ==0) {
        result.add(iter1.next());
    } else {
        result.add(iter2.next());
    }
    i++;
}

a = result;

}

I know it's not perfect at all. But I can't understand how to merge in the 1st list without creating tmp list.

Thanks in advance for taking part.

2

2 Answers 2

0

Double ArrayList a's size. Set last two elements of a to the last element of the old a and the last element of b. Keep going, backing up each time, until you reach the beginnings of a and b. You have to do it from the rear because otherwise you will write over the original a's values.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, John ! Solution is so simple ! As always.
0

In the end i got this:

public static void merge(ArrayList<Integer> arr1, ArrayList<Integer> arr2) {
        int indexForArr1 = arr1.size() - 1;
        int oldSize = arr1.size();
        int newSize = arr1.size() + arr2.size();

        /*
            decided not to create new arraylist with new size but just to fill up old one with nulls
         */
        fillWithNulls(arr1, newSize);

        for(int i = (newSize-1); i >= 0; i--) {
            if (i%2 != 0) {
                int indexForArr2 = i%oldSize;
                arr1.set(i,arr2.get(indexForArr2));
                oldSize--; // we reduce the size because we don't need tha last element any more
            } else {
                arr1.set(i, arr1.get(indexForArr1));
                indexForArr1--;
            }
        }
    }

    private static void fillWithNulls(ArrayList<Integer> array, int newSize) {
        int delta = newSize - array.size();
        for(int i = 0; i < delta; i++) {
            array.add(null);
        }
    }

Thanks John again for bright idea!

3 Comments

It'd be a little more efficient to use oldSize - 1 in your for loop and set elements i * 2 and i * 2 + 1 of arr1 in each iteration. You'd get rid of the two %s and the if that way. And use ArrayList.ensureCapacity to efficiently allocate memory for the larger arr1.
i'll try to replace oldsize var later ArrayList.ensureCapacity is obvious, again)
Only now I remembered about put(index, object) method in List collection

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.