题目
Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the resulting image.
To flip an image horizontally means that each row of the image is reversed. For example, flipping [1, 1, 0] horizontally results in [0, 1, 1].
To invert an image means that each 0 is replaced by 1, and each 1 is replaced by 0. For example, inverting [0, 1, 1] results in [1, 0, 0].
Example 1:
Input: [[1,1,0],[1,0,1],[0,0,0]] Output: [[1,0,0],[0,1,0],[1,1,1]] Explanation: First reverse each row: [[0,1,1],[1,0,1],[0,0,0]]. Then, invert the image: [[1,0,0],[0,1,0],[1,1,1]]
Example 2:
Input: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] Output: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] Explanation: First reverse each row: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]. Then invert the image: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
Notes:
代码语言:javascript复制1 <= A.length = A[0].length <= 20
0 <= A[i][j] <= 1
分析
题意: 将所有数据进行以下操作
- flip an image horizontally ==> 水平翻转,就是逆置 110翻转011
- invert an image ==> 转换成图 0变1,1变0 然后返回数据
分析: 如果按部就班,很容易看出第二步用取反运算即可,第一步则需要逆置。
但是,二进制有二进制的规律,不难想出: 如果逆置前后相同,则结果直接取反;如 11 逆置得11,取反得 00,跟直接取反相同 如果逆置前后不同,则不进行转换;如 10 逆置得01,取反得10,跟原数相同
由于需要判断逆置前后,因此只需要行的一半数据即可。
解答
代码语言:javascript复制class Solution {
public int[][] flipAndInvertImage(int[][] A) {
//拿到每一行数据
for(int[] B:A){
//遍历每一行的一半数据即可
for(int i=0;i*2<B.length;i ){
//如果当前数据跟逆置后的数据相等
if(B[B.length-i-1]==B[i]){
// 则让其取反
B[i]= B[B.length-i-1]^=1;
}
}
}
return A;
}
}
这道解法的亮点有两处
B[i]= B[B.length-i-1]^=1;
由于我们在if条件中已经判断过了B[i] == B[B.length-i-1]
因此,这就是两个相同的数,但是却必须这样写。 运算顺序是这样的(方便起见令(x=B[i]) = (B[B.length-i-1]=y)) x= y^=1; 先拿到y与1进行异或操作,假设现在x=y=1,则y^=1得到y=0 然后x=y,使x得到取反遍历每一行的一半数据
用的是i*2<B.length
而不是i*<B.length/2
,有什么区别呢? 当length为奇数时,比如length=3,那么B.length/2=1相当于下取整除法,然后3位数只需要判断第一个数就够了,而我们的x和y应当指向不同位置的相同数才能计算成功,因此会出现错误, 如果使用i*2<B.length,length=3,那么i最大为1,因此避免了多余的判断。 也就是说,i*2<B.length
比i*<B.length/2
更靠近中心值