Skip to content

Commit a673a50

Browse files
committed
feat: add solutions for lc No.1886
1 parent c22298e commit a673a50

10 files changed

Lines changed: 333 additions & 521 deletions

File tree

solution/1800-1899/1886.Determine Whether Matrix Can Be Obtained By Rotation/README.md

Lines changed: 111 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,13 @@ tags:
6464

6565
<!-- solution:start -->
6666

67-
### 方法一:模拟旋转
67+
### 方法一:原地比较
6868

69-
旋转矩阵,判断矩阵是否一致,旋转方式同 [48. 旋转图像](https://leetcode.cn/problems/rotate-image/)
69+
我们观察矩阵的轮转规律,发现对于矩阵中的元素 $\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]$ 的位置。
70+
71+
因此,我们可以用一个整数 $\textit{ok}$ 来记录当前轮转的状态,初始值为 $0b1111$,表示四种轮转状态都可能。对于矩阵中的每个元素,我们比较它在不同轮转状态下的位置与目标矩阵中的对应位置的元素是否相等,如果不相等,则将对应的轮转状态从 $\textit{ok}$ 中去掉。最后,如果 $\textit{ok}$ 不为零,说明至少有一种轮转状态可以使矩阵与目标矩阵一致,返回 $\textit{true}$;否则,返回 $\textit{false}$。
72+
73+
时间复杂度 $O(n^2)$,其中 $n$ 是矩阵的大小。空间复杂度 $O(1)$。
7074

7175
<!-- tabs:start -->
7276

@@ -75,61 +79,50 @@ tags:
7579
```python
7680
class Solution:
7781
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
78-
def rotate(matrix):
79-
n = len(matrix)
80-
for i in range(n // 2):
81-
for j in range(i, n - 1 - i):
82-
t = matrix[i][j]
83-
matrix[i][j] = matrix[n - j - 1][i]
84-
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1]
85-
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1]
86-
matrix[j][n - i - 1] = t
87-
88-
for _ in range(4):
89-
if mat == target:
90-
return True
91-
rotate(mat)
92-
return False
82+
n = len(mat)
83+
ok = 0b1111
84+
for i in range(n):
85+
for j in range(n):
86+
if mat[i][j] != target[i][j]:
87+
ok &= ~0b0001
88+
if mat[j][n - 1 - i] != target[i][j]:
89+
ok &= ~0b0010
90+
if mat[n - 1 - i][n - 1 - j] != target[i][j]:
91+
ok &= ~0b0100
92+
if mat[n - 1 - j][i] != target[i][j]:
93+
ok &= ~0b1000
94+
if ok == 0:
95+
return False
96+
return ok != 0
9397
```
9498

9599
#### Java
96100

97101
```java
98102
class Solution {
99103
public boolean findRotation(int[][] mat, int[][] target) {
100-
int times = 4;
101-
while (times-- > 0) {
102-
if (equals(mat, target)) {
103-
return true;
104-
}
105-
rotate(mat);
106-
}
107-
return false;
108-
}
109-
110-
private void rotate(int[][] matrix) {
111-
int n = matrix.length;
112-
for (int i = 0; i < n / 2; ++i) {
113-
for (int j = i; j < n - 1 - i; ++j) {
114-
int t = matrix[i][j];
115-
matrix[i][j] = matrix[n - j - 1][i];
116-
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
117-
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
118-
matrix[j][n - i - 1] = t;
119-
}
120-
}
121-
}
122-
123-
private boolean equals(int[][] nums1, int[][] nums2) {
124-
int n = nums1.length;
125-
for (int i = 0; i < n; ++i) {
126-
for (int j = 0; j < n; ++j) {
127-
if (nums1[i][j] != nums2[i][j]) {
104+
int n = mat.length;
105+
int ok = 0b1111;
106+
for (int i = 0; i < n; i++) {
107+
for (int j = 0; j < n; j++) {
108+
if (mat[i][j] != target[i][j]) {
109+
ok &= ~0b0001;
110+
}
111+
if (mat[j][n - 1 - i] != target[i][j]) {
112+
ok &= ~0b0010;
113+
}
114+
if (mat[n - 1 - i][n - 1 - j] != target[i][j]) {
115+
ok &= ~0b0100;
116+
}
117+
if (mat[n - 1 - j][i] != target[i][j]) {
118+
ok &= ~0b1000;
119+
}
120+
if (ok == 0) {
128121
return false;
129122
}
130123
}
131124
}
132-
return true;
125+
return ok != 0;
133126
}
134127
}
135128
```
@@ -141,15 +134,27 @@ class Solution {
141134
public:
142135
bool findRotation(vector<vector<int>>& mat, vector<vector<int>>& target) {
143136
int n = mat.size();
144-
for (int k = 0; k < 4; ++k) {
145-
vector<vector<int>> g(n, vector<int>(n));
146-
for (int i = 0; i < n; ++i)
147-
for (int j = 0; j < n; ++j)
148-
g[i][j] = mat[j][n - i - 1];
149-
if (g == target) return true;
150-
mat = g;
137+
int ok = 0b1111;
138+
for (int i = 0; i < n; ++i) {
139+
for (int j = 0; j < n; ++j) {
140+
if (mat[i][j] != target[i][j]) {
141+
ok &= ~0b0001;
142+
}
143+
if (mat[j][n - 1 - i] != target[i][j]) {
144+
ok &= ~0b0010;
145+
}
146+
if (mat[n - 1 - i][n - 1 - j] != target[i][j]) {
147+
ok &= ~0b0100;
148+
}
149+
if (mat[n - 1 - j][i] != target[i][j]) {
150+
ok &= ~0b1000;
151+
}
152+
if (ok == 0) {
153+
return false;
154+
}
155+
}
151156
}
152-
return false;
157+
return ok != 0;
153158
}
154159
};
155160
```
@@ -158,79 +163,61 @@ public:
158163
159164
```go
160165
func findRotation(mat [][]int, target [][]int) bool {
161-
n := len(mat)
162-
for k := 0; k < 4; k++ {
163-
g := make([][]int, n)
164-
for i := range g {
165-
g[i] = make([]int, n)
166-
}
167-
for i := 0; i < n; i++ {
168-
for j := 0; j < n; j++ {
169-
g[i][j] = mat[j][n-i-1]
170-
}
171-
}
172-
if equals(g, target) {
173-
return true
174-
}
175-
mat = g
176-
}
177-
return false
178-
}
166+
n := len(mat)
167+
ok := 0b1111
179168
180-
func equals(a, b [][]int) bool {
181-
for i, row := range a {
182-
for j, v := range row {
183-
if v != b[i][j] {
184-
return false
185-
}
186-
}
187-
}
188-
return true
169+
for i := 0; i < n; i++ {
170+
for j := 0; j < n; j++ {
171+
if mat[i][j] != target[i][j] {
172+
ok &= ^0b0001
173+
}
174+
if mat[j][n-1-i] != target[i][j] {
175+
ok &= ^0b0010
176+
}
177+
if mat[n-1-i][n-1-j] != target[i][j] {
178+
ok &= ^0b0100
179+
}
180+
if mat[n-1-j][i] != target[i][j] {
181+
ok &= ^0b1000
182+
}
183+
if ok == 0 {
184+
return false
185+
}
186+
}
187+
}
188+
189+
return ok != 0
189190
}
190191
```
191192

192193
#### TypeScript
193194

194195
```ts
195196
function findRotation(mat: number[][], target: number[][]): boolean {
196-
for (let k = 0; k < 4; k++) {
197-
rotate(mat);
198-
if (isEqual(mat, target)) {
199-
return true;
200-
}
201-
}
202-
return false;
203-
}
197+
const n = mat.length;
198+
let ok = 0b1111;
204199

205-
function isEqual(A: number[][], B: number[][]) {
206-
const n = A.length;
207200
for (let i = 0; i < n; i++) {
208201
for (let j = 0; j < n; j++) {
209-
if (A[i][j] !== B[i][j]) {
202+
if (mat[i][j] !== target[i][j]) {
203+
ok &= ~0b0001;
204+
}
205+
if (mat[j][n - 1 - i] !== target[i][j]) {
206+
ok &= ~0b0010;
207+
}
208+
if (mat[n - 1 - i][n - 1 - j] !== target[i][j]) {
209+
ok &= ~0b0100;
210+
}
211+
if (mat[n - 1 - j][i] !== target[i][j]) {
212+
ok &= ~0b1000;
213+
}
214+
if (ok === 0) {
210215
return false;
211216
}
212217
}
213218
}
214-
return true;
215-
}
216219

217-
function rotate(matrix: number[][]): void {
218-
const n = matrix.length;
219-
for (let i = 0; i < n >> 1; i++) {
220-
for (let j = 0; j < (n + 1) >> 1; j++) {
221-
[
222-
matrix[i][j],
223-
matrix[n - 1 - j][i],
224-
matrix[n - 1 - i][n - 1 - j],
225-
matrix[j][n - 1 - i],
226-
] = [
227-
matrix[n - 1 - j][i],
228-
matrix[n - 1 - i][n - 1 - j],
229-
matrix[j][n - 1 - i],
230-
matrix[i][j],
231-
];
232-
}
233-
}
220+
return ok !== 0;
234221
}
235222
```
236223

@@ -240,92 +227,29 @@ function rotate(matrix: number[][]): void {
240227
impl Solution {
241228
pub fn find_rotation(mat: Vec<Vec<i32>>, target: Vec<Vec<i32>>) -> bool {
242229
let n = mat.len();
243-
let mut is_equal = [true; 4];
230+
let mut ok: i32 = 0b1111;
231+
244232
for i in 0..n {
245233
for j in 0..n {
246-
if is_equal[0] && mat[i][j] != target[i][j] {
247-
is_equal[0] = false;
234+
if mat[i][j] != target[i][j] {
235+
ok &= !0b0001;
248236
}
249-
if is_equal[1] && mat[i][j] != target[j][n - 1 - i] {
250-
is_equal[1] = false;
237+
if mat[j][n - 1 - i] != target[i][j] {
238+
ok &= !0b0010;
251239
}
252-
if is_equal[2] && mat[i][j] != target[n - 1 - i][n - 1 - j] {
253-
is_equal[2] = false;
240+
if mat[n - 1 - i][n - 1 - j] != target[i][j] {
241+
ok &= !0b0100;
254242
}
255-
if is_equal[3] && mat[i][j] != target[n - 1 - j][i] {
256-
is_equal[3] = false;
243+
if mat[n - 1 - j][i] != target[i][j] {
244+
ok &= !0b1000;
257245
}
258-
}
259-
}
260-
is_equal.into_iter().any(|&v| v)
261-
}
262-
}
263-
```
264-
265-
<!-- tabs:end -->
266-
267-
<!-- solution:end -->
268-
269-
<!-- solution:start -->
270-
271-
### 方法二:原地比较
272-
273-
此题不同于 [48. 旋转图像](https://leetcode.cn/problems/rotate-image/),并不要求改动原数组,因此,只要比较对应的位置即可。
274-
275-
| 旋转度数 | A | B |
276-
| -------- | ------ | -------------- |
277-
| 0 | `i, j` | `i, j` |
278-
| 90 | `i, j` | `j, n - i` |
279-
| 180 | `i, j` | `n - i, n - j` |
280-
| 270 | `i, j` | `n - j, i` |
281-
282-
> `n = A.length - 1 = B.length - 1`
283-
284-
<!-- tabs:start -->
285-
286-
#### Python3
287-
288-
```python
289-
class Solution:
290-
def findRotation(self, mat: List[List[int]], target: List[List[int]]) -> bool:
291-
for _ in range(4):
292-
mat = [list(col) for col in zip(*mat[::-1])]
293-
if mat == target:
294-
return True
295-
return False
296-
```
297-
298-
#### Java
299-
300-
```java
301-
class Solution {
302-
public boolean findRotation(int[][] mat, int[][] target) {
303-
int n = mat.length;
304-
for (int k = 0; k < 4; ++k) {
305-
int[][] g = new int[n][n];
306-
for (int i = 0; i < n; ++i) {
307-
for (int j = 0; j < n; ++j) {
308-
g[i][j] = mat[j][n - i - 1];
309-
}
310-
}
311-
if (equals(g, target)) {
312-
return true;
313-
}
314-
mat = g;
315-
}
316-
return false;
317-
}
318-
319-
private boolean equals(int[][] a, int[][] b) {
320-
int n = a.length;
321-
for (int i = 0; i < n; ++i) {
322-
for (int j = 0; j < n; ++j) {
323-
if (a[i][j] != b[i][j]) {
246+
if ok == 0 {
324247
return false;
325248
}
326249
}
327250
}
328-
return true;
251+
252+
ok != 0
329253
}
330254
}
331255
```

0 commit comments

Comments
 (0)