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
- 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.
- 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.
- 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.