Given an m x n
matrix
, return all elements of the matrix
in spiral order.
For example:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]
What is the time complexity? What is the space complexity? What are the edge cases?
Given a matrix (2D array), the task is to traverse the matrix in a spiral order and return all elements in that order.
A brute-force approach involves simulating the spiral traversal directly.
top
, bottom
, left
, and right
representing the boundaries of the matrix.left <= right
and top <= bottom
.left
to right
along the top
row.top + 1
to bottom
along the right
column.right - 1
to left
along the bottom
row.bottom - 1
to top + 1
along the left
column.def spiral_matrix_naive(matrix):
result = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while left <= right and top <= bottom:
# Traverse top row
for i in range(left, right + 1):
result.append(matrix[top][i])
top += 1
# Traverse right column
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1
if top <= bottom and left <= right:
# Traverse bottom row
for i in range(right, left - 1, -1):
result.append(matrix[bottom][i])
bottom -= 1
# Traverse left column
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1
return result
Where 'm' is the number of rows and 'n' is the number of columns in the matrix, as each element is visited once.
Excluding the output array, the algorithm uses constant extra space.
The optimal approach is essentially the same as the naive approach because every element of the matrix needs to be visited to produce the spiral order, therefore no optimization can reduce the overall time complexity. The key to the optimal approach is clarity and conciseness in the implementation.
def spiral_matrix_optimized(matrix):
if not matrix:
return []
result = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
# Traverse top row
for i in range(left, right + 1):
result.append(matrix[top][i])
top += 1
# Traverse right column
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1
if top <= bottom and left <= right:
# Traverse bottom row
for i in range(right, left - 1, -1):
result.append(matrix[bottom][i])
bottom -= 1
# Traverse left column
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1
return result
Where 'm' is the number of rows and 'n' is the number of columns in the matrix.
Excluding the output list, the algorithm uses constant extra space.