Jack L. Jack L. - 5 months ago 122
Java Question

Alternating between two arraylists.

I am having trouble getting this thing to run. I'm not sure if what I have so far is on the right track. I'm not quite sure where is is giving me an out of bounds error.

Here are the instructions:

Write a method called interleave that accepts two ArrayLists of integers a1 and a2 as parameters and inserts the elements of a2 into a1 at alternating indexes. If the lists are of unequal length, the remaining elements of the longer list are left at the end of a1. For example, if a1 stores [10, 20, 30] and a2 stores [4, 5, 6, 7, 8], the call of interleave(a1, a2); should change a1 to store [10, 4, 20, 5, 30, 6, 7, 8]. If a1 had stored [10, 20, 30, 40, 50] and a2 had stored [6, 7, 8], the call of interleave(a1, a2); would change a1 to store [10, 6, 20, 7, 30, 8, 40, 50].

private static void interleave(ArrayList<Integer> a1,
ArrayList<Integer> a2) {

int i = a1.size();
int j = a2.size();

if (i < j) { // a1 is shorter than a2
for (int k = 0; k < a1.size(); k++) { // before k passes a1 size
a1.add(k+1, a2.get(k));
}

for (int l = a1.size(); l < a2.size(); l++) {
a1.add(a1.size(), a2.get(l));
}

} else if (i > j) { // a1 is longer than a2
for (int k = 1; k < a2.size(); k++) {
a1.add(k+1, a2.get(k));
}

} else { // they are equal length
for (int k = 1; k < a2.size(); k++) {
a1.add(k+1, a2.get(k));
}
}
}

Answer

This should work

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    int i = -1;
    for(Integer elem: a2) {
        if(i < a1.size()-1) {
            i += 2;
        } else {
            i += 1;
        }
        a1.add(i, elem);
    }
}

public static void main(String[] args) throws Exception {

    ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
    ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

    interleave(a1, a2);
    System.out.println(a1);
}

edit: I have to admit, that this code is actually a pretty bad solution, because it's gonna be very slow for long lists. Every time an element is added to a1, a big part of the list has to be shifted by one position. So following the advice from "MadProgrammer", here is a much better and much much faster way to do it

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    ArrayList<Integer> r = new ArrayList<>(a1.size() + a2.size());

    for(int i = 0, j = 0; i < a1.size() || j < a2.size(); i++, j++) {
        if(i < a1.size()) r.add(a1.get(i));
        if(j < a2.size()) r.add(a2.get(j));
    }
    a1.clear();
    a1.addAll(r);
}
Comments