【leetcode-medium】Score After Flipping Matrix【寻找结果最优化的规则】

题目:

We have a two dimensional matrix A where each value is 0 or 1.

A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0s to 1s, and all 1s to 0s.

After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers.

Return the highest possible score.

Example 1:

Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation:
Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]].
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39

Note:

  1. 1 <= A.length <= 20
  2. 1 <= A[0].length <= 20
  3. A[i][j] is 0 or 1.

解答

解法1:

  • 【先考虑列,再考虑行】
  • 【列变换】列的变换不会造成数量级的变化(同一列在同一数量级上),所以追求1个数的最大化.即变换数量(0) > 数量(1)的情况。
  • 【行变换】每次变化都会造成数量级的变化。所以目标是使第一位为1(量级最大)。
class Solution {
 private  boolean canStop = false;
    public int matrixScore(int[][] A) {
        if(A == null){
            return 0;
        }
        int rowLen = A.length;
        if(rowLen == 0) return 0;
        int colLen = A[0].length;

        while(!canStop){
            moveCols(A,rowLen,colLen);
            moveRows(A,rowLen,colLen);
        }

        int result = generateNum(A,rowLen,colLen);
        return result;
    }

    private int generateNum(int[][] A,int rowLen,int colLen) {
        int result = 0;
        for(int row = 0;row < rowLen;row++){
            StringBuilder sb = new StringBuilder();
            for(int col = 0; col < colLen;col++){
                sb.append(A[row][col]);
            }
            result += Integer.valueOf(sb.toString(),2);
        }
        return result;
    }

    //先纵向,后横向。
    //纵向: 按照零得个数
    //横向:左边0优先于右边。(最右边有一个0则变)

    private void moveCols(int[][] A,int rowLen,int colLen) {
        canStop = true;
        for(int col = 0; col < colLen;col++){
            if(isRightCol(col,A)){
                changeCol(col,A);
                canStop = false;
            }
        }
    }

    private void moveRows( int[][] A,int rowLen,int colLen) {
        canStop = true;
        for(int row = 0;row < rowLen;row++){
            if(isRightRow(row,A)){
                changeRow(row,A);
                canStop = false;
            }
        }
    }

    public boolean isRightRow(int row,int[][] A){
        return A[row][0] == 0;
    }

    public void changeRow(int row, int[][] A){
        for(int c = 0; c < A[0].length; c++){
            if(A[row][c] == 0){
                A[row][c] = 1;
            }else{
                A[row][c] = 0;
            }
        }
    }

    public boolean isRightCol(int col,int[][] A){
        int zroNum = 0;
        for(int r = 0; r < A.length; r++){
            if(A[r][col] == 0){
                zroNum ++;
            }
        }
        return zroNum > A.length/2;
    }
    public void changeCol(int col, int[][] A){
        for(int r = 0; r < A.length; r++){
            if(A[r][col] == 0){
                A[r][col] = 1;
            }else{
                A[r][col] = 0;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/TheSnowBoy_2/article/details/81590136