Home > Net >  Rotate matrix elements for ArrayList<ArrayList<String>> in java
Rotate matrix elements for ArrayList<ArrayList<String>> in java

Time:12-16

I already did search a lot and got a lot of solutions for the rotate matrix but all of them are 2D arrays, for example arr[][] but for my case, my matrix is ArrayList<ArrayList<String>>. So it is natural that it might not be equal in row and column. For example, my matrix is -

1-2-3
4-5-6-6 //Here column is 4 not 3 like the 1-2-3 or 7-8-9 rows 
7-8-9

My target is to make my ArrayList<ArrayList<String>> matrix rotate into a clockwise or anti-clockwise and make it equal in a row and column size. For example-

1-2-3-0         1-4-7
4-5-6-6   ==>   2-5-8
7-8-9-0         3-6-9
                0-6-0

How to optimally achieve this purpose?

CodePudding user response:

Assuming your original list elemnts are always different from 0 you could iterate over each column and collect the elemnts of each row and add 0 for any row which size is to short and stop when all elemnts equal 0. Something like:

public static void main(String[] args) {

    List<List<String>> matrix = List.of( List.of("1", "2", "3"),
                                         List.of("4", "5", "6", "6"),
                                         List.of("7", "8", "9"));

    List<List<String>> rotated =
            IntStream.iterate(0, i -> i   1)
                     .mapToObj(i -> matrix.stream()
                                          .map(sublist -> i < sublist.size() ? sublist.get(i) : "0")
                                          .toList())
                     .takeWhile(list -> !list.stream().allMatch(e -> "0".equals(e)))
                     .toList();
    
    rotated.forEach(System.out::println);
}

CodePudding user response:

public List<List<String>> rotate(List<List<String>> matrix) {
    int maxRowLength = matrix.stream().map(List::size)
            .max(Comparator.naturalOrder()).orElse(0);
    return IntStream.range(0, maxRowLength)
            .mapToObj(i -> matrix.stream()
                    .map(l -> l.size() <= i ? "0" : l.get(i)).toList())
            .toList();
}

Explanation

This approach starts by getting the length of the longest row in the matrix:

matrix.stream().map(List::size).max(Comparator.naturalOrder()).orElse(0)

It then creates a stream which iterates through all possible list indexes: the ints between 0 and the max row length:

IntStream.range(0, maxRowLength)

For each index i in that list, it maps the index to a list. Each element of this list is the ith element of the corresponding list in the matrix, or "0" if that list is shorter than i:

.mapToObj(i -> matrix.stream()
        .map(l -> l.size() <= i ? "0" : l.get(i)).toList())

Finally, it converts the stream to a list:

.toList();
  • Related