861. Score after flipping the matrix

Posted by Vivid Lust on Sun, 13 Feb 2022 10:16:31 +0100

Address:

Force bucklehttps://leetcode-cn.com/problems/score-after-flipping-matrix/

Title:

There is A two-dimensional matrix , A, where the value of each element is , 0 , or , 1.

Move refers to selecting any row or column and converting each value in the row or column: change all 0 to 1 and all 1 to 0.

After making any number of moves, each row of the matrix is interpreted according to binary numbers, and the score of the matrix is the sum of these numbers.

Returns the highest possible score.

Example:

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

Tips:

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

Source: LeetCode
Link: https://leetcode-cn.com/problems/score-after-flipping-matrix
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.

Idea:

For a binary representation, if you want a large number, the high bit should be equal to 1 as much as possible

For example:

So for a matrix that expresses binary numbers like this

Each line is a binary number. The first goal is to set all the highest bits to 1

Phase I:

So we scan column 0 of each row. If the value is not 0, we flip the row

First line:

        

Second line:

        

The third line is not 0. No line transformation is performed

Phase II:

We can't do row transformation anymore. If we do it again, the highest bit may change. At this stage, we deal with column transformation

The starting column starts from the first column and compares the number of 0 elements and 1 elements in this column

Only when the number of 1 element is more, the sum of addition is greater

The first column: all 1, no transformation

The second column: 0:2, 1:1, column transformation

                

The third column: 0:2, 1:1, column transformation

                 

Phase III:

After the first two stages, we get the final matrix, and the rest is to traverse the matrix rows

Convert binary number to decimal number

For example: 1 0 1

                1*2^3 + 1*2^2 + 0*2^1 + 1*2^0

In the implementation part, you need to create two additional two-dimensional arrays

Or the original matrix:

Row arrayNumber of elements 0Number of elements 1

countRowArr

[0][0] = 3[0][1] = 1
[1][0] = 3[1][1] = 1
[2][0] = 2[2][1] = 2

Column arrayNumber of elements 0Number of elements 1

countColArr

[0][0] = 2[0][1] = 1
[1][0] = 2[1][1] = 1
[2][0] = 2[2][1] = 1
[3][0] = 2[3][1] = 1

 

When it is determined that row transformation or column transformation is required, the values of the above two-dimensional arrays shall be updated accordingly

Method 1: dynamically update the value

There are a little more codes. The main logic is as follows:

1. Create two 2D arrays

2. Line transformation

3. Column transformation

4. After the transformation is completed, calculate the binary decimal value

    int **countRowArr = createCountGrid(grid, row, col, "row");
    int **countColArr = createCountGrid(grid, row, col, "col");
   

    /* reverse */
    for(i=0; i<row; i++)
    {
        if(grid[i][0] == 0)
        {
            doReverse(grid, row, col, i, -1, countRowArr, countColArr, "row");
        }
    }


    for(i=1; i<col; i++)
    {
        if( needReverse(countColArr, i) )
            doReverse(grid, row, col, -1, i, countRowArr, countColArr, "col");
    }


    /* caculate */
    for(i=0; i<row; i++)
    {
        ret += cacul(grid[i], col);
    }


The rest of the code is to realize the above functions, and the following is the whole code:

int ** createCountGrid(int **grid, int row, int col, char *content)
{
    int i,j;

    if(strcmp(content, "row") == 0)
    {
        /* store numbers of 0 1 in each row */
        int **countRowArr = (int **)malloc(sizeof(int *) * row);
        for(i=0; i<row; i++)
        {
            countRowArr[i] = (int *)malloc(sizeof(int) * 2);
        }

        /* init countRowArr */
        for(i=0; i<row; i++)
        {
            int zero = 0, one = 0;
            for(j=0; j<col; j++)
            {
                if(grid[i][j] == 0)
                    zero++;
                else
                    one++;
            }
            countRowArr[i][0] = zero;
            countRowArr[i][1] = one;
        }

        return countRowArr;
    }
    else
    {
        /* store numbers of 0 1 in each col */
        int **countColArr = (int **)malloc(sizeof(int *) * col);
        for(i=0; i<col; i++)
        {
            countColArr[i] = (int *)malloc(sizeof(int) * 2);
        }

        /* init countColArr */
        for(j=0; j<col; j++)
        {
            int zero = 0, one = 0;
            for(i=0; i<row; i++)
            {
                if(grid[i][j] == 0)
                    zero++;
                else
                    one++;
            }
            countColArr[j][0] = zero;
            countColArr[j][1] = one;
        }

        return countColArr;
    }

    return NULL;
}

void freeCountGrid(int **grid, int row, int col, char *content)
{
    int i;
    int drow, dcol;

    if(strcmp(content, "row") == 0)
        drow = row;
    else
        drow = col;

    for(i=0; i<drow; i++)
    {
        free(grid[i]);
    }
    free(grid);
}

void dispGrid(int **grid, int row, int col, char *content)
{
    int i, j;
    int drow, dcol;

    if(strcmp(content, "row") == 0)
    {
        drow = row;
        dcol = 2;
    }
    else if(strcmp(content, "col") == 0)
    {
        drow = col;
        dcol = 2;
    }
    else
    {
        drow = row;
        dcol = col;
    }

    for(i=0; i<drow; i++)
    {
        for(j=0; j<dcol; j++)
        {
            printf("disp...%s, grid[%d][%d]=%d\n", content, i, j, grid[i][j]);
        }
    }
}

bool needReverse(int **countArr, int idx)
{
    if(countArr[idx][0] >= countArr[idx][1])
        return true;
    else
        return false;

    return false;
}

void doReverse(int **grid, int row, int col, int revRowIdx, int revColIdx, int **countRowArr, int **countColArr, char *content)
{
    int i;

    if(strcmp(content, "row") == 0) // reverse row
    {
        for(i=0; i<col; i++)
        {
            if(grid[revRowIdx][i] == 0)
            {
                grid[revRowIdx][i] = 1;
                countRowArr[revRowIdx][0] --;
                countRowArr[revRowIdx][1] ++;
                countColArr[i][0] --;
                countColArr[i][1] ++;    
            }
            else
            {
                grid[revRowIdx][i] = 0;
                countRowArr[revRowIdx][0] ++;
                countRowArr[revRowIdx][1] --;
                countColArr[i][0] ++;
                countColArr[i][1] --;
            }
        }
    }
    else
    {
        for(i=0; i<row; i++)
        {
            if(grid[i][revColIdx] == 0)
            {
                grid[i][revColIdx] = 1;

                countColArr[revColIdx][0] --;
                countColArr[revColIdx][1] ++;
                countRowArr[i][0] --;
                countRowArr[i][1] ++;
            }
            else
            {
                grid[i][revColIdx] = 0;

                countColArr[revColIdx][0] ++;
                countColArr[revColIdx][1] --;
                countRowArr[i][0] ++;
                countRowArr[i][1] --;
            }
        }
    }
}

int cacul(int *arr, int len)
{
    int num = 0;
    int k = 0;

    for(int i=len-1; i>=0; i--)
    {
        if(arr[k++] == 0)
            continue;

        int j = i;
        int tmp = 1;
        while(j)
        {
            tmp *= 2;
            j--;
        }
        num += tmp;
    }

    return num;
}

int matrixScore(int** grid, int gridSize, int* gridColSize){
    int i, j;
    int ret = 0;
    int row = gridSize;
    int col = gridColSize[0];

    int **countRowArr = createCountGrid(grid, row, col, "row");
    int **countColArr = createCountGrid(grid, row, col, "col");
    
    // dispGrid(grid, row, col, "all");
    // dispGrid(countRowArr, row, col, "row");
    // dispGrid(countColArr, row, col, "col");

    /* reverse */
    for(i=0; i<row; i++)
    {
        if(grid[i][0] == 0)
        {
            doReverse(grid, row, col, i, -1, countRowArr, countColArr, "row");
        }
    }

    // dispGrid(grid, row, col, "all");
    // dispGrid(countRowArr, row, col, "row");
    // dispGrid(countColArr, row, col, "col");

    for(i=1; i<col; i++)
    {
        if( needReverse(countColArr, i) )
            doReverse(grid, row, col, -1, i, countRowArr, countColArr, "col");
    }

    //dispGrid(grid, row, col, "all");
    // dispGrid(countRowArr, row, col, "row");
    // dispGrid(countColArr, row, col, "col");

    /* caculate */
    for(i=0; i<row; i++)
    {
        ret += cacul(grid[i], col);
    }

    /* free */
    freeCountGrid(countRowArr, row, col, "row");
    freeCountGrid(countColArr, row, col, "col");

    return ret;
}

 

View more brush notes

Topics: leetcode greedy algorithm