Skip to content

Commit a82b722

Browse files
committed
2021.2.24
1 parent 170f4fa commit a82b722

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#### [832. 翻转图像](https://leetcode-cn.com/problems/flipping-an-image/)
2+
3+
给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。
4+
5+
水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]
6+
7+
反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]
8+
9+
```
10+
示例 1:
11+
12+
输入:[[1,1,0],[1,0,1],[0,0,0]]
13+
输出:[[1,0,0],[0,1,0],[1,1,1]]
14+
解释:首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]];
15+
然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]
16+
示例 2:
17+
18+
输入:[[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]]
19+
输出:[[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
20+
解释:首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]];
21+
然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
22+
23+
24+
提示:
25+
26+
1 <= A.length = A[0].length <= 20
27+
0 <= A[i][j] <= 1
28+
```
29+
30+
#### 解题思路(双指针+一次遍历)
31+
32+
最直观的做法是首先对矩阵 A 的每一行进行水平翻转操作,然后对矩阵中的每个元素进行反转操作。该做法需要遍历矩阵两次。
33+
34+
是否可以只遍历矩阵一次就完成上述操作?答案是肯定的。
35+
36+
假设矩阵的行数和列数都是 n,考虑列下标 `left``right`,其中 `left<right``left+right=n−1`,当 `0≤i<n` 时,对第 i 行进行水平翻转之后,`A[i][left] ``A[i][right] `的元素值会互换,进行反转之后,`A[i][left] ``A[i][right] `的元素值都会改变。
37+
38+
具体而言,考虑以下四种情况。
39+
40+
- 情况一:`A[i][left] `=0, `A[i][right] `=0。对第 i 行进行水平翻转之后,`A[i][left] `=0, `A[i][right] `=0。进行反转之后,`A[i][left] `=1, `A[i][right] `=1。
41+
42+
- 情况二:`A[i][left] `=1, `A[i][right] `=1。对第 i 行进行水平翻转之后,`A[i][left] `=1, `A[i][right] `=1。进行反转之后,`A[i][left] `=0, `A[i][right] `=0。
43+
44+
- 情况三:`A[i][left] `=0, `A[i][right] `=1。对第 i 行进行水平翻转之后,`A[i][left] `=1, `A[i][right] `=0。进行反转之后,`A[i][left] `=0, `A[i][right] `=1。
45+
46+
- 情况四:`A[i][left] `=1, `A[i][right] `=0。对第 ii 行进行水平翻转之后,`A[i][left] `=0, `A[i][right] `=1。进行反转之后,`A[i][left] `=1, `A[i][right] `=0。
47+
48+
情况一和情况二是 `A[i][left] ` = `A[i][right] `的情况。在进行水平翻转和反转之后,`A[i][left] ``A[i][right] ` 的元素值都发生了改变,即元素值被反转。
49+
50+
情况三和情况四是 `A[i][left] ``A[i][right] `的情况。在进行水平翻转和反转之后,`A[i][left] ``A[i][right] `的元素值都发生了两次改变,恢复原状。
51+
52+
因此,可以遍历矩阵一次即完成水平翻转和反转。
53+
54+
- 遍历矩阵的每一行。对于矩阵的第 i 行,初始化 `left=0``right=n−1`,进行如下操作:
55+
-`left<right` 时,判断 `A[i][left] ``A[i][right] `是否相等,如果相等则对`A[i][left] ``A[i][right] `的值进行反转,如果不相等则不进行任何操作;
56+
-`left` 的值加 1,将 `right` 的值减 1,重复上述操作,直到 `left≥right`
57+
58+
**如果 n 是奇数,则上述操作结束时,`left``right` 的值相等,都指向第 i 行的中间元素,此时需要对中间元素的值进行反转。**
59+
60+
**代码演示(Golang)**
61+
62+
```go
63+
func flipAndInvertImage(A [][]int) [][]int {
64+
for _, row := range A {
65+
left, right := 0, len(row)-1
66+
for left < right {
67+
if row[left] == row[right] {
68+
row[left] ^= 1
69+
row[right] ^= 1
70+
}
71+
left++
72+
right--
73+
}
74+
// n 是奇数,left和right的值相等,都指向第 i 行的中间元素,此时需要对中间元素的值进行反转。
75+
if left == right {
76+
row[left] ^= 1
77+
}
78+
}
79+
return A
80+
}
81+
82+
```
83+
84+
> 时间复杂度:O(n<sup>2</sup>),其中 n 是矩阵 A 的行数和列数。需要遍历矩阵一次,进行翻转操作。
85+
>
86+
> 空间复杂度:O(1)。除了返回值以外,额外使用的空间为常数。
87+
>

0 commit comments

Comments
 (0)