class Solution { private record Coord(int x, int y) { public void assign(int[] coord) { coord[0] = y; coord[1] = x; } public Coord add(Coord rhs) { return new Coord(x + rhs.x, y + rhs.y); } } private static final List DIRECTIONS = Arrays.asList(new Coord(1, 0), new Coord(0, 1), new Coord(-1, 0), new Coord(0, -1)); private boolean inBounds(int rows, int cols, Coord pos) { return pos.y() >= 0 && pos.y() < rows && pos.x() >= 0 && pos.x() < cols; } public int[][] spiralMatrixIII(int rows, int cols, int rStart, int cStart) { int[][] matrix = new int[rows * cols][2]; var pos = new Coord(cStart, rStart); for (int i = 0, step = 1, direction = 0; i < matrix.length; ++step) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < step; ++k) { if (inBounds(rows, cols, pos)) { pos.assign(matrix[i]); ++i; } pos = pos.add(DIRECTIONS.get(direction)); } direction = (direction + 1) % 4; } } return matrix; } }