Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.
Example 1:
Input: n = 3 Output: [[1,2,3],[8,9,4],[7,6,5]]
Example 2:
Input: n = 1 Output: [[1]]
Constraints:
1 <= n <= 20When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine walking around the outside of a square and filling in numbers one by one, then spiraling inwards. The brute force approach simulates this filling process directly, step by step, by manually keeping track of where you are and where you're allowed to go next.
Here's how the algorithm would work step-by-step:
def spiral_matrix_ii(matrix_size):
matrix = [[0] * matrix_size for _ in range(matrix_size)]
current_number = 1
row = 0
column = 0
row_direction = 0
column_direction = 1
for _ in range(matrix_size * matrix_size):
matrix[row][column] = current_number
current_number += 1
next_row = row + row_direction
next_column = column + column_direction
# Check to see if next move is out of bounds or spot is filled
if (next_row < 0 or next_row >= matrix_size or
next_column < 0 or next_column >= matrix_size or
matrix[next_row][next_column] != 0):
# Change direction when encountering a filled cell
if column_direction == 1:
row_direction = 1
column_direction = 0
elif row_direction == 1:
row_direction = 0
column_direction = -1
elif column_direction == -1:
row_direction = -1
column_direction = 0
else:
row_direction = 0
column_direction = 1
next_row = row + row_direction
next_column = column + column_direction
row = next_row
column = next_column
return matrixThe optimal approach involves filling the matrix layer by layer, moving in a spiral pattern. We simulate the movement in a clockwise direction, filling the top row, then the right column, then the bottom row, and finally the left column, and then repeating this process inwards until the center is reached.
Here's how the algorithm would work step-by-step:
def generate_spiral_matrix(matrix_size):
spiral_matrix = [[0] * matrix_size for _ in range(matrix_size)]
current_number = 1
start_row, end_row = 0, matrix_size - 1
start_col, end_col = 0, matrix_size - 1
while start_row <= end_row and start_col <= end_col:
# Traverse top row
for column in range(start_col, end_col + 1):
spiral_matrix[start_row][column] = current_number
current_number += 1
start_row += 1
# Traverse right column
for row in range(start_row, end_row + 1):
spiral_matrix[row][end_col] = current_number
current_number += 1
end_col -= 1
# This condition checks if inner layer exists
if start_row <= end_row and start_col <= end_col:
# Traverse bottom row
for column in range(end_col, start_col - 1, -1):
spiral_matrix[end_row][column] = current_number
current_number += 1
end_row -= 1
# Traverse left column
for row in range(end_row, start_row - 1, -1):
spiral_matrix[row][start_col] = current_number
current_number += 1
start_col += 1
return spiral_matrix| Case | How to Handle |
|---|---|
| n is zero or negative | Return an empty matrix immediately as a spiral matrix of size n <= 0 is not defined. |
| n is one | Return a 1x1 matrix with the single element 1. |
| n is a large number (integer overflow potential for calculating total elements) | While unlikely with typical constraints, use long integers if language constraints require it to prevent possible overflow during element assignment in extremely large n. |
| Integer overflow when incrementing the counter | The counter increment is checked only to n*n so integer limit checks aren't needed unless n*n is extremely large, if so, proper overflow checks should be implemented. |
| Incorrect loop termination leading to out-of-bounds access | The carefully managed boundaries (top, bottom, left, right) ensure the algorithm only iterates through valid matrix cells. |
| Confusing the order of traversal (right, down, left, up) | Maintain a consistent traversal order and update boundary variables after each layer is completed to prevent incorrect spiral formation. |
| Incorrect boundary updates leading to double processing of elements | Update boundaries (top, bottom, left, right) only after a full side is traversed to ensure correct spiral construction without redundant entries. |
| Memory allocation issues for very large n | Pre-allocate the matrix and ensure sufficient memory to avoid runtime errors, and consider using generators if possible to create the matrix in smaller chunks. |