zoukankan      html  css  js  c++  java
  • 861.翻转矩阵后的得分

    有一个二维矩阵 A 其中每个元素的值为 0 或 1 。

    移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0。

    在做出任意次数的移动后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。

    返回尽可能高的分数。

    示例:

    输入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
    输出:39
    解释:
    转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
    0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39

    提示:

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

    解决这个问题首先要解决什么呢?就是找到什么时候返回值最大,毫无疑问,最高位最大时整个数最大,也就是说,整个矩阵首列都要为1,所以遍历整个矩阵首列,如果该位为0,就把该行翻转(翻转操作对1异或即可)。

    接下来处理首列之外的数据,因为第一列已经为1,所以不能进行行翻转了,就遍历之后的列,如果0多就进行翻转。

    处理完数据之后,矩阵就变成了我们想要的矩阵,从第一列开始,把整列加起来,然后依次乘2加列和,最后得到的结果就是我们要的值,

    	class Solution {
    		//要想值最大,第一列必须都为1,所以先遍历每一行,把首位为0的翻转
    		//然后从第二列开始,如果是0多久翻转,1多就不变
    	    public int matrixScore(int[][] A) {
    	    	int res = 0;
                //对首位为0的行进行翻转
    	    	for(int i = 0; i < A.length; i++) {
    	    		if(A[i][0] == 0) {
    	    			reverse(A[i]);
    	    		}
    	    	}
                //处理第一列之后的数据,按列来处理
    	    	for(int j = 1; j < A[0].length; j++) {
    	    		int num = 0;
    	    		for(int i = 0; i < A.length; i++) {
    	    			if(A[i][j] == 0) {
    	    				num++;
    	    			}
    	    			if(num > A.length/2) {
    	    				for(int k = 0; k < A.length; k++) {
    	    					A[k][j] ^= 1;
    	    				}
    	    				break;
    	    			}
    	    		}
    	    	}
                //计算结果
    	    	for(int j = 0; j < A[0].length; j++) {
    	    		res = res << 1;
    	    		for(int i = 0; i < A.length; i++) {
    	    			res += A[i][j];
    	    		}
    	    	}
    	    	return res;
    	    }
            public void reverse(int[] arr) {
    	    	for(int i = 0; i < arr.length; i++) {
    	    		arr[i] ^= 1;
    	    	}
    	    }
        }
    

    但是这样处理并不是最优解,因为我们要想想我们要的结果是什么,只是一个最大值。但是在求这个最大值的过程中我们对矩阵做了很多没必要的操作,于是对解法进行优化。

    第一步还是不变,对首位为0的行进行翻转。

    重点在第二步和求和的过程中,我们开始做的是如果0的个数大于列长度的一半,就翻转,这个操作的目的是把列中大多数变成1,最后相加。但是仔细一想,最后都是1相加,这个1的个数就是一列中0和1数量的较大值,所以我们没有必要对0进行翻转,只是计算数量即可,并且在计算数量的过程中就可以求出返回值。

    	class Solution {
    		//看到的新解法
    		//首先把第一列全部变成1,res加上行数(因为第一列全部为1)
    		//然后再遍历之后的每一列,0和1比较大的那个数量就是我们要的(省去了翻转的过程)
    		//res * 2 再加上这个数量,遍历完就是我们要的结果
    	    public int matrixScore(int[][] A) {
    	    	int res = 0;
    	    	res += A.length;
    	    	for(int i = 0; i < A.length; i++) {
    	    		if(A[i][0] == 0) {
    	    			for(int j = 0; j < A[0].length; j++) {
    	    				A[i][j] ^= 1;
    	    			}
    	    		}
    	    	}
    	    	for(int j = 1; j < A[0].length; j++) {
    	    		int num = 0;
    	    		for(int i = 0; i < A.length; i++) {
    	    			if(A[i][j] == 1) {
    	    				num++;
    	    			}
    	    		}
    	    		num = Math.max(num, A.length-num);
    	    		res = (res << 1) + num;
    	    	}
    	    	return res;
    	    }
        }
    
  • 相关阅读:
    Spring加载xsd引起的问题小记
    kafka配置参数
    nginx常见内部参数,错误总结
    从毕业到现在的总结
    storm坑之---传递对象
    Java多线程读取大文件
    webpack4.0.1安装问题及解决方法
    git入门篇shell
    less教程
    原生js的ajax请求
  • 原文地址:https://www.cnblogs.com/Jiewl/p/12578331.html
Copyright © 2011-2022 走看看