Eric Smith
Eric Smith

Reputation: 51

Adding Squared Elements of an Arraylist to said Arraylist

I am trying to add the squared elements for back into the original arraylist. For example [1,2,3] should become [1, 1, 2, 4, 3, 9]. My issue is I am not sure if my machine is just bad because I am getting an out of memory error. Here is my attempt. The recursive call is just to get the sum of the arraylist.

public static int sumOfSquares(List<Integer> num) {


    if (num.isEmpty()) {
        return 0;
    }
    for(int i=0; i<num.size();i++){
        int hold= num.get(i)*num.get(i);
        num.add(hold);
    }


    return num.get(0) + sumOfSquares(num.subList(1, num.size()));
}

Upvotes: 1

Views: 1265

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726849

The problem with your implementation is that it does not distinguish original numbers from the squares that you have previously added.

First, since you are doing this recursively, you don't need a for loop. Each invocation needs to take care of the initial value of the list alone.

Next, add(n) adds the number at the end, while your example shows adding numbers immediately after the original value. Therefore, you should use num.add(1, hold), and skip two initial numbers when making a recursive call.

Here is how the fixed method should look:

public static int sumOfSquares(List<Integer> num) {
    if (num.isEmpty()) {
        return 0;
    }
    // Deal with only the initial element
    int hold= num.get(0)*num.get(0);
    // Insert at position 1, right after the squared number
    num.add(1, hold);
    // Truncate two initial numbers, the value and its square:
    return num.get(1) + sumOfSquares(num.subList(2, num.size()));
}

Demo.

Upvotes: 1

castletheperson
castletheperson

Reputation: 33496

There are two ways to safely add (or remove) elements to a list while iterating it:

  1. Iterate backwards over the list, so that the indexes of the upcoming elements don't shift.

  2. Use an Iterator or ListIterator.

You can fix your code using either strategy, but I recommend a ListIterator for readable code.

import java.util.ListIterator;

public static void insertSquares(List<Integer> num) {
    ListIterator<Integer> iter = num.listIterator();
    while (iter.hasNext()) {
        int value = iter.next();
        iter.add(value * value);
    }
}

Then, move the summing code into a separate method so that the recursion doesn't interfere with the inserting of squares into the list. Your recursive solution will work, but an iterative solution would be more efficient for Java.

Upvotes: 0

Related Questions