# 885. Spiral Matrix III

You start at the cell `(rStart, cStart)` of an `rows x cols` grid facing east. The northwest corner is at the first row and column in the grid, and the southeast corner is at the last row and column.

You will walk in a clockwise spiral shape to visit every position in this grid. Whenever you move outside the grid's boundary, we continue our walk outside the grid (but may return to the grid boundary later.). Eventually, we reach all `rows * cols` spaces of the grid.

Return *an array of coordinates representing the positions of the grid in the order you visited them*.

### Thoughts

* Immediately I wanted to create a 2D array for some reason, but I don't think that is necessary to actually solve this problem
    
* this seems relatively straight forward, just have to keep track of which cells are actually part of the grid
    
* testing for completion is probably as simple as checking that you have visited `rows * cols` cells
    
* i think using placeholder variables that keep track of the last horizontal and vertical distances traveled before turning would be the way to go, and then just checking along the way that the current indices are within the bounds of the rows and columns of the grid
    

### Solution

```java
class Solution {
    public int[][] spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
        int[][] coords = new int[rows * cols][2];
        int curRow = rStart;
        int curCol = cStart;
        int lastHorizontal = 0;
        int lastVertical = 0;
        int curCoord = 0;

        coords[curCoord] = new int[]{rStart, cStart};
        curCoord++;

        while (curCoord < rows * cols) {
            // Right
            lastHorizontal++;
            for (int i = 0; i < lastHorizontal; i++) {
                curCol++;
                if ((curRow < rows && curRow >= 0) && (curCol < cols && curCol >= 0)) {
                    coords[curCoord] = new int[]{curRow, curCol};
                    curCoord++;
                }
            }

            // Down
            lastVertical++;
            for (int i = 0; i < lastVertical; i++) {
                curRow++;
                if ((curRow < rows && curRow >= 0) && (curCol < cols && curCol >= 0)) {
                    coords[curCoord] = new int[]{curRow, curCol};
                    curCoord++;
                }
            }

            // Left
            lastHorizontal++;
            for (int i = 0; i < lastHorizontal; i++) {
                curCol--;
                if ((curRow < rows && curRow >= 0) && (curCol < cols && curCol >= 0)) {
                    coords[curCoord] = new int[]{curRow, curCol};
                    curCoord++;
                }
            }

            // Up
            lastVertical++;
            for (int i = 0; i < lastVertical; i++) {
                curRow--;
                if ((curRow < rows && curRow >= 0) && (curCol < cols && curCol >= 0)) {
                    coords[curCoord] = new int[]{curRow, curCol};
                    curCoord++;
                }
            }
        }

        return coords;
    }
}
```

**Time Complexity:** O(`rows * columns`) == O(n)  
**Space Complexity:** O(`rows * columns`)

### Conclusion

This was actually a really fun problem in my opinion. The solution was pretty straightforward and I was able to get it implemented fairly quickly, it just took some debugging because of some silly errors. Like for when I was traversing left/right I was actually moving up/down, and vice-versa, and it took a while for me to figure that out. Overall though this problem was actually really fun.
