0

I am learning Jjava and I found an interesting exercise on ArrayLists. The purpose is to write a function partition() which takes a parameter list and a parameter size and returns a list of sub-list, where each sub-list has the maximum size element.

For example:

  • partition([1,2,3,4,5], 2) should return [ [1,2], [3,4], [5] ],
  • partition([1,2,3,4,5], 3) should return [ [1,2,3], [4,5] ],
  • partition([1,2,3,4,5], 1) should return [ [1], [2], [3], [4], [5] ].

I did this but it works only if the parameter size is equal to 1 and I want to do it for all cases, and I'm struggling if someone can help me, please.

public static void main(String[] args) {
    Apside t = new Apside();
    ArrayList<Integer> a = new ArrayList<Integer>();
    a.add(1);
    a.add(2);
    a.add(3);
    a.add(4);
    System.out.println(t.partition(a, 1));
}

public ArrayList<ArrayList> partition(ArrayList<Integer> l, int n) {
    ArrayList<ArrayList> al = new ArrayList();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < l.size(); j++) {
            for(int k =0; k<n; k++){
                ArrayList<Integer> list = new ArrayList(n);
                int b = l.get(j);
                list.add(b);
                al.add(list);
            }



        }
    }
    return al;
}
MarianD
  • 13,096
  • 12
  • 42
  • 54
user395817
  • 185
  • 2
  • 2
  • 12

2 Answers2

0

You can use subList method.

public ArrayList<ArrayList> partition(List<Integer> li, int n) {
    ArrayList<ArrayList> al = new ArrayList();
    int start = 0;
    int i=n;
    for(; i<li.size(); i+=n){
        List<Integer> lis = li.subList(start, i);
        ArrayList<Integer> list = new ArrayList<>();
        list.addAll(lis);
        al.add(list);
        start = i;
    }

    if(i >= li.size()){
        List<Integer> lis = li.subList(start, li.size());
        ArrayList<Integer> list = new ArrayList<>();
        list.addAll(lis);
        al.add(list);
    }
    return al;
}
Shivam Pokhriyal
  • 1,044
  • 11
  • 26
0

I was trying to understand your solution but unfortunately I don't get it. Your outer loop is wrong: the outer-most loop should definitely be from 0 to the size of the list and not to the size of partition.

The next thing is your inner-most loop. Each time you're inside you're creating a new list, add one element to it and add this list to your result. It doesn't make any sense. Most likely you wanted something like this (body of the middle loop)

List<Integer> list = new ArrayList<Integer>(n);
for (...) {
    ...
    int b = l.get(j);
    list.add(b);
    ...
}
al.add(list);

But it still doesn't work as you introduced a third loop which is definitely not necessary here. To make your solution reliable you need only 2 loops (first - going through the whole list and second going through current partition:

public static List<List<Integer>> partition(List<Integer> l, int n) {
    List<List<Integer>> al = new ArrayList<>();
    for (int i = 0; i < l.size(); i += n) {
        List<Integer> list = new ArrayList<>();
        for (int j = i; j < i + n && j < l.size(); j++) {
            list.add(l.get(j));
        }
        al.add(list);
    }
    return al;
}

Take a look at the boundaries I choose: outer loop goes from 0 to the size of the list with a step of partition size, while inner loop goes from the current index of outer loop up to the partition size or list size, whichever comes first.

There is a much simpler solution:

private static List<List<?>> partition(List<?> list, int size) {
    var result = new ArrayList<List<?>>();
    for (int i = 0; i < list.size(); i += size) {
        result.add(new ArrayList<>(list.subList(i, Math.min(i + size, list.size()))));
    }
    return result;
}

This is a generic approach where you can pass a list of any elements (not just integers) and get a partitioned result. Here again is a loop which goes from 0 to a list size with a partition size step and every time get a sublist of original list according to partition size or just a remaining elements if there is less than full partition.

Also, as a side note. Take a look at my code using interfaces (List) instead of implementations (ArrayList) and using generic types (ArrayList<>(), List<Integer>(), List<?> instead of raw-types (ArrayList())

Dmitry Smorzhok
  • 635
  • 11
  • 21