给定一个二进制矩阵 A
,我们想先水平翻转图像,然后反转图像并返回结果。
水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0]
的结果是 [0, 1, 1]
。
反转图片的意思是图片中的 0
全部被 1
替换, 1
全部被 0
替换。例如,反转 [0, 1, 1]
的结果是 [1, 0, 0]
。
示例 1:
输入: [[1,1,0],[1,0,1],[0,0,0]] 输出: [[1,0,0],[0,1,0],[1,1,1]] 解释: 首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]]; 然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]
示例 2:
输入: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] 输出: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] 解释: 首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]; 然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
说明:
1 <= A.length = A[0].length <= 20
0 <= A[i][j] <= 1
解析:
该题目就是兑换每一行中对应的元素,然后再将所有元素0->1,1->0.步骤比较简单,本文用了两个双重循环来实现。看到有大佬给出了更好的答案。(1)找到了规律,如果需要兑换的两个数字相等,则两个数字都从0->1或1->0.如果不相等,则翻转行再翻转图片后的结果和原来的值一样,所以不需要改变。(2)只需要一次双重循环,在兑换的同时,实现反转图片。
代码:
//两个双重循环
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A)
{
int row = A.size();
int col = A[0].size();
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col/2; j++)
{
swap(A[i][j], A[i][col - j - 1]);//翻转行
}
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
A[i][j] = 1 - A[i][j];//翻转图片
}
}
return A;
}
他山之石:
//翻转的同时反转图片
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) {
int colums = A[0].size();
for(vector<int> &row : A){
for(int i=0; i< (colums+1)/2; ++i){
int temp = row[i] ^ 1;//用异或实现
row[i] = row[colums-1-i] ^ 1;
row[colums-1-i] = temp;
}
}
return A;
}
//根据规律只反转相等的值
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) {
int N = A.size();
for (int i = 0; i < N;++i)
{
int j = 0, k = N - 1;
while (j <= k)
{
if (A[i][j] == A[i][k])
A[i][j] = A[i][k] = (1 ^ A[i][k]);
j++; k--;
}
}
return A;
}