LeetCode0861.翻转矩阵后的得分

版权声明:啦啦啦,不用于商业的话随便拿,记得带上博客地址http://blog.csdn.net/wjoker https://blog.csdn.net/wjoker/article/details/82958181

861.翻转矩阵后的得分

描述

有一个二维矩阵 A 其中每个元素的值为 01

移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 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. 1 <= A.length <= 20
  2. 1 <= A[0].length <= 20
  3. A[i][j]01

题解

一个矩阵计算每一行的二进制之和,也就是每一列中权重都是相同的,那么只要尽可能让每一排的第一个元素是1并且每一列中的1尽可能多

  • 检查每一行的开头,如果值为0就将这一行翻转
  • 检查每一列中10的个数,如果0多就将这一列翻转
public static int matrixScore(int[][] A) {
    int h = A.length;
    int w = A[0].length;
    int[] shuiPing = new int[h];//记录每一列中1的个数
    int[] chuiZhi = new int[w];//记录每一排中1的个数

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            shuiPing[i] += A[i][j];
            chuiZhi[j] += A[i][j];
        }
    }

    boolean isChange = true;

    while (isChange){
        isChange = false;
        for (int i = 0; i < w; i++) {
            if (h-chuiZhi[i] > chuiZhi[i]){
                for (int j = 0; j < h; j++) {
                    if ((A[j][i] == 1)) {
                        A[j][i] = 0;
                        shuiPing[j]--;
                        chuiZhi[i]--;
                    } else {
                        A[j][i] = 1;
                        shuiPing[j]++;
                        chuiZhi[i]++;
                    }
                }
                isChange = true;
            }
        }

        for (int i = 0; i < h; i++) {
            if (A[i][0] == 0){
                for (int j = 0; j < w; j++) {
                    if ((A[i][j] == 1)) {
                        A[i][j] = 0;
                        shuiPing[i]--;
                        chuiZhi[j]--;
                    } else {
                        A[i][j] = 1;
                        shuiPing[i]++;
                        chuiZhi[j]++;
                    }
                }
                isChange = true;
            }
        }
    }

    int sum = 0;

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            sum += A[i][j] * Math.pow(2,w-j-1);
        }
    }
    return sum;
}

查看范例代码看到一个更加精简的.

  • 每一行的第一个元素都可以通过对列翻转将其变成1
  • 完成了上一步之后,每一列中1的数量可以通过翻转变成这一列中Math.max(num(0),num(1))
    public int matrixScore(int[][] A) {
        int m = A.length;
        int n = A[0].length;
        int sum = 0;
        for(int i = 0; i < m; i++) {
            if(A[i][0] == 0) {
                for(int j = 0; j < n; j++) {
                    A[i][j] = 1 - A[i][j];
                }
            }
        }
        sum += m * (int)Math.pow(2, n - 1);
        for(int j = 1; j < n; j++) {
            int count = 0;
            for(int i = 0; i < m; i++) {
                if(A[i][j] == 1) {
                   count ++;
                }
            }
            if(2 * count < m) {
                count = m - count;
            }
            sum += count * (int)Math.pow(2, n - j - 1);
        }
        return sum;
    }

猜你喜欢

转载自blog.csdn.net/wjoker/article/details/82958181