问题描述
给定一个二进制矩阵 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
解题思路
1、每个矩阵的子数组从左到右,从右到左,同时比较更改,如果数值不同,则不需要改变,因为翻转后再反转数值最后是一样的,如果数值一样,则需要反转一次,用 ^=或者 1-当前数值
2、如果有一个中间的数,则直接反转就行
第一种
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int len=A.length;
if(A==null||len!=A[0].length && len<=20) //避免行数和列数不等得情况
return null;
for(int i=0;i<len;i++){
int left=0, right=len-1;
while(left < right){ //只比较前一半就行了
if(A[i][left] == A[i][right]){ //如果不等得情况,比喻 0,1,先翻转变成1,0, 再反转,又会还原成0,1,
A[i][left]^=1; //所以这里只需要比较相等得情况就行了,相等得话,一定得取反值
A[i][right]^=1; //^=如果两个值都为1 ,则为0,如果不等1,则为1 也可以A[i][right]=1-A[i][right];
}
left++;
right--;
}
if(left == right){ //如果有最中间得,则取反就行了
A[i][left]^=1;
}
}
return A;
}
}
第二种,暴力解法
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int len=A.length;
if(A==null||len!=A[0].length && len<=20)
return null;
int [][]res=new int[len][len];
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
res[i][len-1-j] = ( A[i][j]==0 ) ? 1 : 0; //如果当前数值为0则把1给res,否则把0给res
}
}
return res;
}
}
补充
总结:
|=:两个二进制对应位都为0时,结果等于0,否则结果等于1;
&=:两个二进制的对应位都为1时,结果为1,否则结果等于0;
^=:两个二进制的对应位相同,结果为0,否则结果为1。