Easy
题目描述
给你两个大小为 n x n 的二进制矩阵 mat 和 target,如果能够使 mat 经过若干次 90 度顺时针旋转得到 target,则返回 true;否则,返回 false。
示例 1:
输入:mat = [[0,1],[1,0]], target = [[1,0],[0,1]]
输出:true
解释:我们可以将 mat 顺时针旋转 90 度,使其等于 target。
示例 2:
输入:mat = [[0,1],[1,1]], target = [[1,0],[0,1]]
输出:false
解释:无论如何旋转 mat,都无法使其等于 target。
示例 3:
输入:mat = [[0,0,0],[0,1,0],[1,1,1]], target = [[1,1,1],[0,1,0],[0,0,0]]
输出:true
解释:我们可以将 mat 顺时针旋转 90 度两次,使其等于 target。
提示:
- n == mat.length == target.length
- n == mat[i].length == target[i].length
- 1 <= n <= 10
- mat[i][j] 和 target[i][j] 都是 0 或 1
解题思路
这道题的核心思路是:一个矩阵最多只需要旋转4次(每次90度)就能回到原状,所以我们只需要检查矩阵旋转0、1、2、3次后是否与目标矩阵相等。
解法分析:
暴力模拟法:直接模拟矩阵的旋转过程,每次将矩阵顺时针旋转90度,然后检查是否等于目标矩阵。矩阵90度顺时针旋转的规律是:
新矩阵[j][n-1-i] = 原矩阵[i][j]优化思路:由于最多只需要旋转4次,我们可以预先生成所有可能的旋转结果,然后逐一比较。
推荐解法: 暴力模拟法,代码简洁且易于理解。
具体步骤:
- 检查当前矩阵是否等于目标矩阵
- 如果不等,旋转90度后继续检查
- 重复最多4次,如果都不匹配则返回false
时间复杂度主要取决于矩阵比较和旋转操作,由于n最大为10,效率完全可以接受。
代码实现
class Solution {
public:
bool findRotation(vector<vector<int>>& mat, vector<vector<int>>& target) {
for (int i = 0; i < 4; i++) {
if (mat == target) return true;
rotate90(mat);
}
return false;
}
private:
void rotate90(vector<vector<int>>& matrix) {
int n = matrix.size();
// 转置
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(matrix[i][j], matrix[j][i]);
}
}
// 水平翻转
for (int i = 0; i < n; i++) {
reverse(matrix[i].begin(), matrix[i].end());
}
}
};
class Solution:
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
for _ in range(4):
if mat == target:
return True
mat = self.rotate90(mat)
return False
def rotate90(self, matrix):
n = len(matrix)
# 转置后水平翻转
return [[matrix[n-1-j][i] for j in range(n)] for i in range(n)]
public class Solution {
public bool FindRotation(int[][] mat, int[][] target) {
for (int i = 0; i < 4; i++) {
if (AreEqual(mat, target)) return true;
Rotate90(mat);
}
return false;
}
private void Rotate90(int[][] matrix) {
int n = matrix.Length;
// 转置
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// 水平翻转
for (int i = 0; i < n; i++) {
Array.Reverse(matrix[i]);
}
}
private bool AreEqual(int[][] mat1, int[][] mat2) {
int n = mat1.Length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mat1[i][j] != mat2[i][j]) return false;
}
}
return true;
}
}
var findRotation = function(mat, target) {
for (let i = 0; i < 4; i++) {
if (areEqual(mat, target)) return true;
rotate90(mat);
}
return false;
};
function rotate90(matrix) {
const n = matrix.length;
// 转置
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
}
}
// 水平翻转
for (let i = 0; i < n; i++) {
matrix[i].reverse();
}
}
function areEqual(mat1, mat2) {
const n = mat1.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (mat1[i][j] !== mat2[i][j]) return false;
}
}
return true;
}
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n²) | 最多旋转4次,每次旋转和比较都是O(n²),常数因子 |
| 空间复杂度 | O(1) | 原地旋转,只使用常数额外空间 |
相关题目
- . Rotate Image (Medium)