Quick Overview

Rotate a 2-D integer matrix by any multiple of 90 degrees, clockwise or counter-clockwise, and return the rotated grid. Square matrices and half turns must be rotated in place with constant extra space, while a quarter turn of a rectangular matrix produces a new matrix with swapped dimensions. It tests index mapping, angle normalization and in-place element movement.

Rotate a Matrix by Any Multiple of 90 Degrees, In Place Where the Shape Allows

Company: Oracle

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

Rotate a 2-D integer matrix by a given angle. The core case is a square `n × n` matrix turned 90 degrees clockwise in place: rearrange the values inside the input matrix itself, using only constant extra space, instead of copying them into a second matrix. Your function must also handle two generalizations: any multiple of 90 degrees in either direction, and rectangular `m × n` matrices. ### Function Signature ```python def rotate_matrix(matrix: list[list[int]], degrees: int) -> list[list[int]]: ``` ### Rules - `matrix` is a list of `m` rows, each a list of `n` integers. - `degrees` is a multiple of 90. A positive value rotates clockwise, a negative value rotates counter-clockwise, and `0` leaves the matrix unchanged. Angles wrap around every full turn, so rotating by `degrees` gives the same result as rotating by `degrees - 360` or `degrees + 360`. - One clockwise quarter turn moves the value at row `r`, column `c` of an `m × n` matrix to row `c`, column `m - 1 - r` of an `n × m` result. A counter-clockwise quarter turn is the inverse of that move, and a half turn is two quarter turns in the same direction. - When the result has the same shape as the input (every square matrix, and any matrix turned by a multiple of 180 degrees), rotate in place: move the values within `matrix` using `O(1)` extra space, without allocating a second matrix, and return `matrix` itself. - When the result has a different shape (a matrix with `m != n` turned by an odd number of quarter turns), return a new `n × m` matrix. - Return the rotated matrix as a list of rows. ### Constraints - `1 <= m <= 200` and `1 <= n <= 200` - `-10^9 <= matrix[r][c] <= 10^9`; values may repeat. - `-10^6 <= degrees <= 10^6` and `degrees % 90 == 0` - Every input value fits in a 32-bit signed integer. ### Examples **Example 1** ```text Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], degrees = 90 Output: [[7, 4, 1], [8, 5, 2], [9, 6, 3]] ``` The first column, read from bottom to top, becomes the first row. The matrix is square, so it is rotated in place and `matrix` itself is returned. **Example 2** ```text Input: matrix = [[1, 2, 3], [4, 5, 6]], degrees = -90 Output: [[3, 6], [2, 5], [1, 4]] ``` A counter-clockwise quarter turn of a 2 × 3 matrix produces a 3 × 2 matrix: the last column, read from top to bottom, becomes the first row. **Example 3** ```text Input: matrix = [[1, 2], [3, 4], [5, 6]], degrees = -540 Output: [[6, 5], [4, 3], [2, 1]] ``` `-540` wraps around to a half turn, because `-540 + 720 = 180`. The shape stays 3 × 2, so the rotation is done in place.

Overview: Rotate a 2-D integer matrix by any multiple of 90 degrees, clockwise or counter-clockwise, and return the rotated grid. Square matrices and half turns must be rotated in place with constant extra space, while a quarter turn of a rectangular matrix produces a new matrix with swapped dimensions. It tests index mapping, angle normalization and in-place element movement.

Rotate a 2-D integer matrix by a given angle and return the rotated matrix. The core case is a square `n × n` matrix turned 90 degrees clockwise in place: rearrange the values inside the input matrix itself, using only constant extra space, instead of copying them into a second matrix. Your function must also handle two generalizations: any multiple of 90 degrees in either direction, and rectangular `m × n` matrices. **Rules** - `matrix` is a list of `m` rows, each a list of exactly `n` integers. - `degrees` is a multiple of 90. A positive value rotates clockwise, a negative value rotates counter-clockwise, and `0` leaves the matrix unchanged. Angles wrap around every full turn, so rotating by `degrees` gives the same result as rotating by `degrees - 360` or `degrees + 360`. - One clockwise quarter turn moves the value at row `r`, column `c` of an `m × n` matrix to row `c`, column `m - 1 - r` of an `n × m` result. A counter-clockwise quarter turn is the inverse of that move, and a half turn is two quarter turns in the same direction. - When the result has the same shape as the input (every square matrix, and any matrix turned by a multiple of 180 degrees), rotate in place: move the values within `matrix` using `O(1)` extra space, without allocating a second matrix, and return `matrix` itself. - When the result has a different shape (a matrix with `m != n` turned by an odd number of quarter turns), return a new `n × m` matrix. - Return the rotated matrix as a list of rows: `n × m` after an odd number of quarter turns, `m × n` otherwise. Only the returned matrix is checked. In C++ the matrix arrives as a `const` reference, so return the rotated matrix by value there. Every input value fits in a 32-bit signed integer and no value can exceed `2^31 - 1`, so `int` is enough in Java and C++. **Example 1** ```text Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], degrees = 90 Output: [[7, 4, 1], [8, 5, 2], [9, 6, 3]] ``` The first column, read from bottom to top, becomes the first row. The matrix is square, so it is rotated in place and `matrix` itself is returned. **Example 2** ```text Input: matrix = [[1, 2, 3], [4, 5, 6]], degrees = -90 Output: [[3, 6], [2, 5], [1, 4]] ``` A counter-clockwise quarter turn of a 2 × 3 matrix produces a 3 × 2 matrix: the last column, read from top to bottom, becomes the first row. **Constraints** - `1 <= m <= 200` and `1 <= n <= 200` - Every row of `matrix` has exactly `n` integers. - `-10^9 <= matrix[r][c] <= 10^9`; values may repeat. - `-10^6 <= degrees <= 10^6` and `degrees % 90 == 0` - Every input value fits in a 32-bit signed integer.

Constraints

  • 1 <= m <= 200 and 1 <= n <= 200
  • Every row of matrix has exactly n integers.
  • -10^9 <= matrix[r][c] <= 10^9; values may repeat.
  • -10^6 <= degrees <= 10^6 and degrees % 90 == 0
  • Every input value fits in a 32-bit signed integer.

Examples

Input: ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 90)

Expected Output: [[7, 4, 1], [8, 5, 2], [9, 6, 3]]

Explanation: Source Example 1: an odd 3 x 3 square turned 90 degrees clockwise in place; the center value 5 stays fixed.

Input: ([[1, 2, 3], [4, 5, 6]], -90)

Expected Output: [[3, 6], [2, 5], [1, 4]]

Explanation: Source Example 2: a wide 2 x 3 matrix turned one quarter counter-clockwise becomes 3 x 2; the last column becomes the first row.

Hints

  1. Rotating by degrees and by degrees plus or minus 360 gives the same matrix, so first reduce the angle to one of four cases, taking care with negative values.
  2. Use the quarter-turn rule from the statement to work out where the value at row r, column c ends up in each of those four cases, and what shape the result has.
  3. Only a non-square matrix turned by an odd number of quarter turns changes shape; in every other case the values can be moved around inside the given matrix.

Loading coding console...

Show the approach

Approach

Reduce the angle to k = (degrees / 90) mod 4 clockwise quarter turns, taking the non-negative remainder so negative angles wrap correctly (-90 gives 3, -540 gives 2, 999990 gives 3, -999990 gives 1). Since degrees is a multiple of 90, the division is exact in every language.

  • k = 0: return matrix unchanged.
  • k = 2: a half turn sends (r, c) to (m - 1 - r, n - 1 - c). Reversing the order of the rows and then reversing every row does exactly that, in place, for any shape.
  • k = 1 or 3 on a square matrix: transpose in place by swapping matrix[i][j] with matrix[j][i] for every j > i, so the value from (r, c) now sits at (c, r). For a clockwise turn, reverse every row, which moves it to (c, n - 1 - r), the clockwise target. For a counter-clockwise turn, reverse the order of the rows instead, which moves it to (n - 1 - c, r), the inverse of the clockwise move.
  • k = 1 or 3 on a non-square matrix: the shape changes, so build a new n x m matrix with result[i][j] = matrix[m - 1 - j][i] for a clockwise turn and result[i][j] = matrix[j][n - 1 - i] for a counter-clockwise turn.

Invariant and correctness: each step is a permutation of cells, and after it every output cell holds exactly the value the quarter-turn rule sends there, so the returned rows are the rotated matrix. The same-shape paths only swap values inside matrix, so they need O(1) extra space.

Edge cases: a 1 x 1 matrix is unchanged by every angle; a single row or column only changes shape, and its order depends on the direction; any multiple of 360 returns the input unchanged. The C++ reference receives a const reference, so it writes the same cells into a new matrix instead of rotating in place.

Time complexity:
O(m * n)
Space complexity:
O(1) extra when the shape is unchanged; O(m * n) for the new n x m matrix when it changes