LeetCode 1886 - Determine Whether Matrix Can Be Obtained By Rotation
The problem gives us two square binary matrices, mat and target, both of size n x n. Each cell contains either 0 or 1. Our task is to determine whether mat can be transformed into target by rotating it clockwise in 90 degree increments. A rotation can be performed multiple times.
Difficulty: 🟢 Easy
Topics: Array, Matrix
Solution
Problem Understanding
The problem gives us two square binary matrices, mat and target, both of size n x n. Each cell contains either 0 or 1. Our task is to determine whether mat can be transformed into target by rotating it clockwise in 90 degree increments.
A rotation can be performed multiple times. Since rotating a square matrix four times returns it to its original orientation, there are only four possible states we need to consider:
- No rotation, 0 degrees
- One rotation, 90 degrees
- Two rotations, 180 degrees
- Three rotations, 270 degrees
If any of these rotated versions matches target, we return true. Otherwise, we return false.
The matrices are guaranteed to be square, and the size constraint is very small:
1 <= n <= 10
This small constraint tells us that efficiency is not a major concern. Even an algorithm with cubic complexity would comfortably pass. However, we still want a clean and logically optimal solution.
An important detail is that the matrix elements are binary, but that fact does not fundamentally change the algorithm. The same logic would work for any values.
Some important edge cases include:
- A
1 x 1matrix, where rotation does nothing. - Matrices that already match without any rotation.
- Matrices that only match after multiple rotations.
- Matrices that never match.
- Symmetric matrices, where multiple rotations may produce the same matrix.
Because the input is guaranteed to be valid square matrices of equal dimensions, we do not need to handle malformed input.
Approaches
Brute Force Approach
The brute force strategy is straightforward. We repeatedly rotate the matrix and compare it with target.
The algorithm works as follows:
- Compare
matwithtarget. - If they match, return
true. - Otherwise, rotate
matclockwise by 90 degrees. - Repeat this process up to four times.
Since there are only four possible orientations, this guarantees that we examine every valid rotation.
To rotate a matrix, we create a new matrix where each element is repositioned according to the rotation rule:
new[j][n - 1 - i] = old[i][j]
Each rotation requires visiting every cell, which costs O(n^2). Each comparison also costs O(n^2). Since we do this at most four times, the total work remains manageable.
This approach is already efficient enough for the problem constraints.
Key Insight for the Optimal Solution
The key observation is that a square matrix has only four unique rotational states. We do not need any advanced search or simulation.
Instead of trying arbitrary transformations, we can systematically generate each rotated version and directly compare it to the target matrix.
Because the number of rotations is constant, the complexity effectively remains proportional to the number of matrix cells.
Approach Comparison
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(4 × n²) | O(n²) | Rotate and compare up to four times |
| Optimal | O(n²) | O(n²) | Same practical approach, since rotations are bounded by four |
Although both rows appear similar, the second framing emphasizes the important observation that the number of rotations is constant.
Algorithm Walkthrough
- Start with the original matrix
mat. - Compare the current matrix with
target.
This check determines whether the current orientation already matches the desired matrix. If they are equal, we can immediately return True.
3. If the matrices do not match, rotate the matrix clockwise by 90 degrees.
For every position (i, j) in the original matrix, place its value into position (j, n - 1 - i) in the rotated matrix.
4. Replace the current matrix with the rotated version.
This allows the next iteration to continue rotating from the current orientation. 5. Repeat the process four times.
Four rotations cover all possible orientations:
- 0 degrees
- 90 degrees
- 180 degrees
- 270 degrees
- If none of the rotations match
target, returnFalse.
Why it works
A square matrix rotated clockwise repeatedly cycles through exactly four possible orientations before returning to its original state. Therefore, checking all four rotations guarantees that we examine every possible valid transformation. If none match the target matrix, then no valid rotation exists.
Python Solution
from typing import List
class Solution:
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
def rotate(matrix: List[List[int]]) -> List[List[int]]:
n = len(matrix)
rotated = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
rotated[j][n - 1 - i] = matrix[i][j]
return rotated
current = mat
for _ in range(4):
if current == target:
return True
current = rotate(current)
return False
The implementation begins by defining a helper function called rotate. This function constructs a new matrix of the same size and fills it according to the clockwise rotation mapping.
The expression:
rotated[j][n - 1 - i] = matrix[i][j]
is the core transformation rule for clockwise rotation.
The variable current stores the current orientation of the matrix. Initially, it references the original mat.
The loop runs four times because there are only four possible rotations. During each iteration:
- The current matrix is compared with
target. - If they are equal, the function immediately returns
True. - Otherwise, the matrix is rotated once for the next iteration.
If all four orientations fail to match, the function returns False.
Go Solution
func findRotation(mat [][]int, target [][]int) bool {
rotate := func(matrix [][]int) [][]int {
n := len(matrix)
rotated := make([][]int, n)
for i := 0; i < n; i++ {
rotated[i] = make([]int, n)
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
rotated[j][n-1-i] = matrix[i][j]
}
}
return rotated
}
isEqual := func(a [][]int, b [][]int) bool {
n := len(a)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if a[i][j] != b[i][j] {
return false
}
}
}
return true
}
current := mat
for k := 0; k < 4; k++ {
if isEqual(current, target) {
return true
}
current = rotate(current)
}
return false
}
The Go solution follows the same logic as the Python implementation, but there are some language specific differences.
Go does not support direct matrix equality comparison for slices, so we define an explicit isEqual helper function that compares each cell manually.
Matrix allocation also requires explicit initialization using make.
The rotation logic itself is identical to the Python version.
Since matrix sizes are very small, there are no concerns about memory usage or integer overflow.
Worked Examples
Example 1
mat =
[
[0,1],
[1,0]
]
target =
[
[1,0],
[0,1]
]
Initial state:
| Rotation | Matrix | Matches Target |
|---|---|---|
| 0 degrees | [[0,1],[1,0]] | No |
Rotate 90 degrees clockwise.
Transformation steps:
| Original Position | Value | New Position |
|---|---|---|
| (0,0) | 0 | (0,1) |
| (0,1) | 1 | (1,1) |
| (1,0) | 1 | (0,0) |
| (1,1) | 0 | (1,0) |
Resulting matrix:
[
[1,0],
[0,1]
]
This matches target, so we return True.
Example 2
mat =
[
[0,1],
[1,1]
]
target =
[
[1,0],
[0,1]
]
Check all four rotations:
| Rotation | Matrix | Match |
|---|---|---|
| 0 degrees | [[0,1],[1,1]] | No |
| 90 degrees | [[1,0],[1,1]] | No |
| 180 degrees | [[1,1],[1,0]] | No |
| 270 degrees | [[1,1],[0,1]] | No |
None match the target matrix, so we return False.
Example 3
mat =
[
[0,0,0],
[0,1,0],
[1,1,1]
]
After the first rotation:
[
[1,0,0],
[1,1,0],
[1,0,0]
]
No match yet.
After the second rotation:
[
[1,1,1],
[0,1,0],
[0,0,0]
]
This equals target, so the algorithm returns True.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n²) | At most four rotations and comparisons |
| Space | O(n²) | Extra matrix created during rotation |
The algorithm performs a constant number of operations on every matrix cell. Since the number of rotations is fixed at four, the constant factor does not affect asymptotic complexity.
The additional space comes from constructing a rotated matrix during each transformation.
Test Cases
from typing import List
class Solution:
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
def rotate(matrix):
n = len(matrix)
rotated = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
rotated[j][n - 1 - i] = matrix[i][j]
return rotated
current = mat
for _ in range(4):
if current == target:
return True
current = rotate(current)
return False
sol = Solution()
# Example 1, matches after one rotation
assert sol.findRotation([[0,1],[1,0]], [[1,0],[0,1]]) == True
# Example 2, impossible to match
assert sol.findRotation([[0,1],[1,1]], [[1,0],[0,1]]) == False
# Example 3, matches after two rotations
assert sol.findRotation(
[[0,0,0],[0,1,0],[1,1,1]],
[[1,1,1],[0,1,0],[0,0,0]]
) == True
# Already equal without rotation
assert sol.findRotation([[1]], [[1]]) == True
# Single element mismatch
assert sol.findRotation([[0]], [[1]]) == False
# Matches after three rotations
assert sol.findRotation(
[[1,0],[0,0]],
[[0,1],[0,0]]
) == True
# Symmetric matrix remains same after rotation
assert sol.findRotation(
[[1,0],[0,1]],
[[1,0],[0,1]]
) == True
# Larger matrix with no valid rotation
assert sol.findRotation(
[[1,0,0],[0,1,0],[0,0,1]],
[[0,1,0],[1,0,0],[0,0,1]]
) == False
Test Summary
| Test | Why |
|---|---|
| Example 1 | Validates single rotation case |
| Example 2 | Validates impossible transformation |
| Example 3 | Validates multiple rotations |
[[1]] vs [[1]] |
Smallest valid matrix |
[[0]] vs [[1]] |
Single cell mismatch |
| Three rotation case | Ensures all four rotations are checked |
| Symmetric matrix | Validates no rotation needed |
| Larger mismatch case | Ensures false negatives are avoided |
Edge Cases
One important edge case is a 1 x 1 matrix. Since rotating a single element matrix changes nothing, the algorithm must correctly identify whether the two values already match. The implementation handles this naturally because all rotations produce the same matrix.
Another important case is when the matrices are already equal before any rotation occurs. A buggy implementation might rotate first and miss this scenario. Our solution checks equality before each rotation, including the original orientation.
A third important edge case involves symmetric matrices. Some matrices remain unchanged after one or more rotations. For example:
[
[1,0],
[0,1]
]
may appear identical under certain transformations. The implementation correctly handles this because it simply compares matrices at every stage without assuming uniqueness between rotations.
A final subtle edge case occurs when the correct answer requires exactly three rotations, 270 degrees clockwise. Some incorrect implementations only check one or two rotations. By iterating exactly four times, our solution guarantees that every valid orientation is examined.