Taro Logo

Spiral Matrix

Medium
2 views
2 months ago

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]

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100
Sample Answer
def spiralOrder(matrix):
    """
    Given an m x n matrix, return all elements of the matrix in spiral order.

    Example 1:
    Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
    Output: [1,2,3,6,9,8,7,4,5]

    Example 2:
    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]
    """
    result = []
    if not matrix:
        return result

    row_start = 0
    row_end = len(matrix) - 1
    col_start = 0
    col_end = len(matrix[0]) - 1

    while row_start <= row_end and col_start <= col_end:
        # Traverse right
        for i in range(col_start, col_end + 1):
            result.append(matrix[row_start][i])
        row_start += 1

        # Traverse down
        for i in range(row_start, row_end + 1):
            result.append(matrix[i][col_end])
        col_end -= 1

        if row_start <= row_end and col_start <= col_end:
            # Traverse left
            for i in range(col_end, col_start - 1, -1):
                result.append(matrix[row_end][i])
            row_end -= 1

            # Traverse up
            for i in range(row_end, row_start - 1, -1):
                result.append(matrix[i][col_start])
            col_start += 1

    return result

Explanation:

The spiralOrder function takes a matrix as input and returns a list of its elements in spiral order. The algorithm works by maintaining four pointers: row_start, row_end, col_start, and col_end, which represent the boundaries of the current spiral layer. The algorithm then iterates through the matrix in a spiral pattern, adding each element to the result list. After each layer is traversed, the boundaries are updated to move to the next inner layer.

  1. Initialization: Initialize an empty list result to store the spiral order elements. Also, initialize the boundary pointers: row_start, row_end, col_start, and col_end.
  2. Outer Loop: The while loop continues as long as the row_start is less than or equal to row_end and col_start is less than or equal to col_end. This ensures that we keep traversing the matrix until we reach the center.
  3. Traverse Right: Iterate from col_start to col_end and add elements of the row_start row to the result list. Increment row_start.
  4. Traverse Down: Iterate from row_start to row_end and add elements of the col_end column to the result list. Decrement col_end.
  5. Check Condition: Before traversing left and up, check if row_start is still less than or equal to row_end and col_start is still less than or equal to col_end. This check is necessary to avoid duplicate traversal in cases where the matrix is not square.
  6. Traverse Left: Iterate from col_end to col_start (in reverse) and add elements of the row_end row to the result list. Decrement row_end.
  7. Traverse Up: Iterate from row_end to row_start (in reverse) and add elements of the col_start column to the result list. Increment col_start.
  8. Return: After the while loop finishes, return the result list.

Big(O) Run-time Analysis:

The time complexity of this algorithm is O(m * n), where m is the number of rows and n is the number of columns in the matrix. This is because each element in the matrix is visited exactly once.

Big(O) Space Usage Analysis:

The space complexity of this algorithm is O(m * n), where m is the number of rows and n is the number of columns in the matrix. This is because the result list stores all the elements of the matrix.

Edge Cases:

  1. Empty Matrix: If the input matrix is empty, the function should return an empty list.
  2. Single Row or Single Column: If the matrix has only one row or one column, the function should still return the elements in the correct order.
  3. Non-square Matrix: The algorithm should work correctly for non-square matrices.
  4. Null Matrix: If the input matrix is null, the function should return an empty list or handle the null input appropriately (e.g., by raising an exception). The provided code implicitly handles this by checking if not matrix.

These edge cases are handled gracefully in the provided code.