Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ tags:

<!-- solution:start -->

### 方法一:模拟旋转
### 方法一:原地比较

旋转矩阵,判断矩阵是否一致,旋转方式同 [48. 旋转图像](https://leetcode.cn/problems/rotate-image/)。
我们观察矩阵的轮转规律,发现对于矩阵中的元素 $\text{mat}[i][j]$,它在轮转 90 度后会出现在 $\text{mat}[j][n-1-i]$ 的位置,在轮转 180 度后会出现在 $\text{mat}[n-1-i][n-1-j]$ 的位置,在轮转 270 度后会出现在 $\text{mat}[n-1-j][i]$ 的位置。

因此,我们可以用一个整数 $\textit{ok}$ 来记录当前轮转的状态,初始值为 $0b1111$,表示四种轮转状态都可能。对于矩阵中的每个元素,我们比较它在不同轮转状态下的位置与目标矩阵中的对应位置的元素是否相等,如果不相等,则将对应的轮转状态从 $\textit{ok}$ 中去掉。最后,如果 $\textit{ok}$ 不为零,说明至少有一种轮转状态可以使矩阵与目标矩阵一致,返回 $\textit{true}$;否则,返回 $\textit{false}$。

时间复杂度 $O(n^2)$,其中 $n$ 是矩阵的大小。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -75,61 +79,50 @@ tags:
```python
class Solution:
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
def rotate(matrix):
n = len(matrix)
for i in range(n // 2):
for j in range(i, n - 1 - i):
t = matrix[i][j]
matrix[i][j] = matrix[n - j - 1][i]
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1]
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1]
matrix[j][n - i - 1] = t

for _ in range(4):
if mat == target:
return True
rotate(mat)
return False
n = len(mat)
ok = 0b1111
for i in range(n):
for j in range(n):
if mat[i][j] != target[i][j]:
ok &= ~0b0001
if mat[j][n - 1 - i] != target[i][j]:
ok &= ~0b0010
if mat[n - 1 - i][n - 1 - j] != target[i][j]:
ok &= ~0b0100
if mat[n - 1 - j][i] != target[i][j]:
ok &= ~0b1000
if ok == 0:
return False
return ok != 0
```

#### Java

```java
class Solution {
public boolean findRotation(int[][] mat, int[][] target) {
int times = 4;
while (times-- > 0) {
if (equals(mat, target)) {
return true;
}
rotate(mat);
}
return false;
}

private void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n / 2; ++i) {
for (int j = i; j < n - 1 - i; ++j) {
int t = matrix[i][j];
matrix[i][j] = matrix[n - j - 1][i];
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
matrix[j][n - i - 1] = t;
}
}
}

private boolean equals(int[][] nums1, int[][] nums2) {
int n = nums1.length;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (nums1[i][j] != nums2[i][j]) {
int n = mat.length;
int ok = 0b1111;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] != target[i][j]) {
ok &= ~0b0001;
}
if (mat[j][n - 1 - i] != target[i][j]) {
ok &= ~0b0010;
}
if (mat[n - 1 - i][n - 1 - j] != target[i][j]) {
ok &= ~0b0100;
}
if (mat[n - 1 - j][i] != target[i][j]) {
ok &= ~0b1000;
}
if (ok == 0) {
return false;
}
}
}
return true;
return ok != 0;
}
}
```
Expand All @@ -141,15 +134,27 @@ class Solution {
public:
bool findRotation(vector<vector<int>>& mat, vector<vector<int>>& target) {
int n = mat.size();
for (int k = 0; k < 4; ++k) {
vector<vector<int>> g(n, vector<int>(n));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
g[i][j] = mat[j][n - i - 1];
if (g == target) return true;
mat = g;
int ok = 0b1111;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (mat[i][j] != target[i][j]) {
ok &= ~0b0001;
}
if (mat[j][n - 1 - i] != target[i][j]) {
ok &= ~0b0010;
}
if (mat[n - 1 - i][n - 1 - j] != target[i][j]) {
ok &= ~0b0100;
}
if (mat[n - 1 - j][i] != target[i][j]) {
ok &= ~0b1000;
}
if (ok == 0) {
return false;
}
}
}
return false;
return ok != 0;
}
};
```
Expand All @@ -158,79 +163,61 @@ public:

```go
func findRotation(mat [][]int, target [][]int) bool {
n := len(mat)
for k := 0; k < 4; k++ {
g := make([][]int, n)
for i := range g {
g[i] = make([]int, n)
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
g[i][j] = mat[j][n-i-1]
}
}
if equals(g, target) {
return true
}
mat = g
}
return false
}
n := len(mat)
ok := 0b1111

func equals(a, b [][]int) bool {
for i, row := range a {
for j, v := range row {
if v != b[i][j] {
return false
}
}
}
return true
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if mat[i][j] != target[i][j] {
ok &= ^0b0001
}
if mat[j][n-1-i] != target[i][j] {
ok &= ^0b0010
}
if mat[n-1-i][n-1-j] != target[i][j] {
ok &= ^0b0100
}
if mat[n-1-j][i] != target[i][j] {
ok &= ^0b1000
}
if ok == 0 {
return false
}
}
}

return ok != 0
}
```

#### TypeScript

```ts
function findRotation(mat: number[][], target: number[][]): boolean {
for (let k = 0; k < 4; k++) {
rotate(mat);
if (isEqual(mat, target)) {
return true;
}
}
return false;
}
const n = mat.length;
let ok = 0b1111;

function isEqual(A: number[][], B: number[][]) {
const n = A.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (A[i][j] !== B[i][j]) {
if (mat[i][j] !== target[i][j]) {
ok &= ~0b0001;
}
if (mat[j][n - 1 - i] !== target[i][j]) {
ok &= ~0b0010;
}
if (mat[n - 1 - i][n - 1 - j] !== target[i][j]) {
ok &= ~0b0100;
}
if (mat[n - 1 - j][i] !== target[i][j]) {
ok &= ~0b1000;
}
if (ok === 0) {
return false;
}
}
}
return true;
}

function rotate(matrix: number[][]): void {
const n = matrix.length;
for (let i = 0; i < n >> 1; i++) {
for (let j = 0; j < (n + 1) >> 1; j++) {
[
matrix[i][j],
matrix[n - 1 - j][i],
matrix[n - 1 - i][n - 1 - j],
matrix[j][n - 1 - i],
] = [
matrix[n - 1 - j][i],
matrix[n - 1 - i][n - 1 - j],
matrix[j][n - 1 - i],
matrix[i][j],
];
}
}
return ok !== 0;
}
```

Expand All @@ -240,92 +227,29 @@ function rotate(matrix: number[][]): void {
impl Solution {
pub fn find_rotation(mat: Vec<Vec<i32>>, target: Vec<Vec<i32>>) -> bool {
let n = mat.len();
let mut is_equal = [true; 4];
let mut ok: i32 = 0b1111;

for i in 0..n {
for j in 0..n {
if is_equal[0] && mat[i][j] != target[i][j] {
is_equal[0] = false;
if mat[i][j] != target[i][j] {
ok &= !0b0001;
}
if is_equal[1] && mat[i][j] != target[j][n - 1 - i] {
is_equal[1] = false;
if mat[j][n - 1 - i] != target[i][j] {
ok &= !0b0010;
}
if is_equal[2] && mat[i][j] != target[n - 1 - i][n - 1 - j] {
is_equal[2] = false;
if mat[n - 1 - i][n - 1 - j] != target[i][j] {
ok &= !0b0100;
}
if is_equal[3] && mat[i][j] != target[n - 1 - j][i] {
is_equal[3] = false;
if mat[n - 1 - j][i] != target[i][j] {
ok &= !0b1000;
}
}
}
is_equal.into_iter().any(|&v| v)
}
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- solution:start -->

### 方法二:原地比较

此题不同于 [48. 旋转图像](https://leetcode.cn/problems/rotate-image/),并不要求改动原数组,因此,只要比较对应的位置即可。

| 旋转度数 | A | B |
| -------- | ------ | -------------- |
| 0 | `i, j` | `i, j` |
| 90 | `i, j` | `j, n - i` |
| 180 | `i, j` | `n - i, n - j` |
| 270 | `i, j` | `n - j, i` |

> `n = A.length - 1 = B.length - 1`

<!-- tabs:start -->

#### Python3

```python
class Solution:
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
for _ in range(4):
mat = [list(col) for col in zip(*mat[::-1])]
if mat == target:
return True
return False
```

#### Java

```java
class Solution {
public boolean findRotation(int[][] mat, int[][] target) {
int n = mat.length;
for (int k = 0; k < 4; ++k) {
int[][] g = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
g[i][j] = mat[j][n - i - 1];
}
}
if (equals(g, target)) {
return true;
}
mat = g;
}
return false;
}

private boolean equals(int[][] a, int[][] b) {
int n = a.length;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (a[i][j] != b[i][j]) {
if ok == 0 {
return false;
}
}
}
return true;

ok != 0
}
}
```
Expand Down
Loading
Loading