Problem

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.

Examples

Example 1:

Input: rows = 1, cols = 4, rStart = 0, cStart = 0
Output: [ [0,0],[0,1],[0,2],[0,3] ]

Example 2:

Input: rows = 5, cols = 6, rStart = 1, cStart = 4
Output: [ [1,4],[1,5],[2,5],[2,4],[2,3],[1,3],[0,3],[0,4],[0,5],[3,5],[3,4],[3,3],[3,2],[2,2],[1,2],[0,2],[4,5],[4,4],[4,3],[4,2],[4,1],[3,1],[2,1],[1,1],[0,1],[4,0],[3,0],[2,0],[1,0],[0,0] ]

Similar Problems

Solution

Method 1 - Simulation

We know that we start from position [rStart, cStart], and we start in direction East, then we go to South, West and north and start the same process.

So, we can define directions:

// Directions: East, South, West, North
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

We add [rStart, cStart] to our answer, and go to east.

Then in each direction we take x steps. Initially x = 1, but then it increases by 1 ( - observe carefully - ) when we completed the steps in 2 directions. In eg. 2, we go from 1 → 2, and then 2 → 3, then our number steps increases to 2. Similarly, now we go to 3 → 5, and 5 → 7, then our number of steps increase to 3. So, we go from 7 → out of bounds (right of 9) and so on. So, each time we ran into 2 directions, we have to increase the number of steps. So, we can loop twice for the same number of steps, and increase our steps after that.

Also, when we have walked full x steps, we change the direction as well.

So, now to the code.

Video Explanation

Here is the video explanation for solving the problem:

Code

Java
public class Solution {
    public int[][] spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
        // Directions: East, South, West, North
        int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        List <int[]> ans = new ArrayList<>();

        // Initial coordinates and direction index
        int r = rStart, c = cStart;
        int directionIdx = 0;
        int steps = 1; // Number of steps to take in current direction
        
        ans.add(new int[] {rStart, cStart}); // Add starting point

        while (ans.size() < rows * cols) {
            for (int i = 0; i < 2; i++) {
                // Looping twice for same number of steps
                for (int j = 0; j < steps; j++) {
                    r += directions[directionIdx][0];
                    c += directions[directionIdx][1];

                    // Check if within bounds
                    if (r >= 0 && r < rows && c >= 0 && c < cols) {
                        ans.add(new int[]{r, c});
                    }
                }
                // Change direction
                directionIdx = (directionIdx + 1) % 4;
            }
            steps++; // Increase the steps after traversing in each direction pair
        }

        return ans.toArray(new int[rows * cols][2]);
    }

}
Python
def spiralOrder(rows, cols, rStart, cStart):
    # Directions: East, South, West, North
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    result = []
    seen = set()

    # Initial coordinates and direction index
    r, c = rStart, cStart
    direction_idx = 0
    steps = 1  # Number of steps to take in the current direction

    ans.append([rStart, cStart])  # Add starting point
    if rows * cols == 1:
        return ans  # Edge case for single cell

    while len(ans) < rows * cols:
        for _ in range(2):  # Run twice for each pair of directions
            for _ in range(steps):
                r += directions[direction_idx][0]
                c += directions[direction_idx][1]

                # Check if within bounds
                if 0 <= r < rows and 0 <= c < cols:
                    ans.append([r, c])

            # Change direction
            direction_idx = (direction_idx + 1) % 4
        steps += 1  # Increase the steps after traversing in each direction pair

    return ans

Complexity

  • ⏰ Time complexity: O(row * cols)
  • 🧺 Space complexity: O(rows * cols)