19 Flipping an Image

关注 每天一道编程题 专栏,一起学习进步。

题目

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:

1 <= A.length = A[0].length <= 20
0 <= A[i][j] <= 1

分析

题意:
将所有数据进行以下操作

  1. flip an image horizontally ==> 水平翻转,就是逆置 110翻转011
  2. invert an image ==> 转换成图 0变1,1变0
    然后返回数据

分析:
如果按部就班,很容易看出第二步用取反运算即可,第一步则需要逆置。

但是,二进制有二进制的规律,不难想出:
如果逆置前后相同,则结果直接取反;如 11 逆置得11,取反得 00,跟直接取反相同
如果逆置前后不同,则不进行转换;如 10 逆置得01,取反得10,跟原数相同

由于需要判断逆置前后,因此只需要行的一半数据即可。

解答

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;
    }
}

这道解法的亮点有两处

  1. 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得到取反
  2. 遍历每一行的一半数据用的是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.lengthi*<B.length/2更靠近中心值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值