861. 翻转矩阵后的得分

地址:

力扣icon-default.png?t=M0H8https://leetcode-cn.com/problems/score-after-flipping-matrix/

题目:

有一个二维矩阵 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/score-after-flipping-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

一个二进制的表示,要想数目大,那么高位尽量等于 1

比如:

那么对于一个这样表达二进制数的矩阵来讲

每一行都是一个二进制数,第一个目标就是把最高位全部置 1

第一阶段:

所以我们扫描每一行的第 0 列,如果值不是 0,就进行行翻转

        第一行:

        

        第二行:

        

        第三行不是 0,不做行变换

第二阶段:

        我们不能再做行变换了,如果再做那么最高位可能就会变,我们这个阶段是处理列变换

       起始列从第 1 列开始,比较的是该列 0 元素的个数,1 元素的个数

        只有 1 元素个数更多的时候,相加的和才更大

        第一列:全部是 1 不做变换

        第二列:0:2个,1:1个,列变换

                

        第三列:0:2个,1:1个,列变换

                 

第三阶段:

        经过前面两个阶段,我们都得到了最终的矩阵,剩下的就是对矩阵行遍历

        转变二进制数为十进制数

        比如:1 1 0 1

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

实现部分,需要额外的创建两个二维数组

还是以原始矩阵说明:

行数组元素 0 的个数元素 1 的个数

countRowArr

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

列数组元素 0 的个数元素 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

 

再判定需要进行 行变换 或 列变换 时,要顺带更新上面这两个二维数组的值

方法一、动态更新值

 代码稍微有点多,主要逻辑先上:

1. 创建两个二维数组

2. 行变换

3. 列变换

4. 变换完成,计算二进制的十进制值

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


 剩余代码为具体实现上面的功能,下面是全代码:

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

 

查看更多刷题笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目描述:翻转矩阵。输入一个矩阵,将矩阵顺时针翻转180度。包括多组输入输出,第一行输入两个数字n和m,表示下面输入的是一个n*m的矩阵。接下来n行输入矩阵,最后输出翻转后的矩阵。 例如: 输入: 3 3 1 2 3 4 5 6 7 8 9 输出: 9 8 7 6 5 4 3 2 1 解析:将矩阵顺时针旋转180度,即先上下翻转,再左右翻转。具体实现可以先上下翻转,再沿着对角线翻转即可。 ### 回答2: 翻转矩阵实际上就是将矩阵旋转180度。我们可以通过以下步骤来实现: 1. 首先读入一个矩阵矩阵的行数为n,列数为m。 2. 然后我们将矩阵的第i行和第n-i行交换位置,这样就完成了上下翻转。 3. 接着我们将矩阵的第j列和第m-j列交换位置,这样就完成了左右翻转。 4. 最后输出翻转后的矩阵即可。 以下是代码实现: ```python n, m = map(int, input().split()) matrix = [] for i in range(n): row = list(map(int, input().split())) matrix.append(row) # 上下翻转 for i in range(n // 2): matrix[i], matrix[n-i-1] = matrix[n-i-1], matrix[i] # 左右翻转 for i in range(n): for j in range(m // 2): matrix[i][j], matrix[i][m-j-1] = matrix[i][m-j-1], matrix[i][j] # 输出结果 for i in range(n): for j in range(m): print(matrix[i][j], end=' ') print() ``` 如果我们输入以下样例: ``` 3 4 1 2 3 4 5 6 7 8 9 10 11 12 ``` 则输出结果为: ``` 12 11 10 9 8 7 6 5 4 3 2 1 ``` 可以看到,矩阵已经完成了顺时针翻转180度。 ### 回答3: 翻转矩阵,指的是将一个矩阵沿着中心对称轴旋转180度。具体方法是先将矩阵上下翻转(即第一行和最后一行交换,第二行和倒数第二行交换,以此类推),然后再左右翻转(即矩阵中每行的元素顺序反转)。这样做后,矩阵就被顺时针翻转了180度。 对于这个问题,我们可以按照以下步骤来实现: 1. 读入矩阵的行数n和列数m。 2. 创建一个n*m的数组matrix,用于存储输入的矩阵。 3. 读入矩阵的元素,并存储到数组matrix中。 4. 对矩阵进行上下翻转: - 从第一行向下遍历到第n/2行,对于每一行,将它和第n-i+1行交换。 5. 对矩阵进行左右翻转: - 对于每一行,从第一列向右遍历到第m/2列,对于每一个位置,将它和第m-j+1列交换。 6. 输出翻转后的矩阵。 具体实现请见以下代码: ```python n, m = map(int, input().split()) matrix = [list(map(int, input().split())) for i in range(n)] # 上下翻转 for i in range(n // 2): matrix[i], matrix[n - i - 1] = matrix[n - i - 1], matrix[i] # 左右翻转 for i in range(n): for j in range(m // 2): matrix[i][j], matrix[i][m - j - 1] = matrix[i][m - j - 1], matrix[i][j] # 输出翻转后的矩阵 for i in range(n): for j in range(m): print(matrix[i][j], end=' ') print() ``` 需要注意的是,在实现时,我们可以只处理矩阵的前一半行和前一半列,因为矩阵的后一半行和后一半列已经被交换过了。另外,要注意输出时的格式,可以在每个元素后面加一个空格来区分不同的元素,以免输出的矩阵看起来杂乱无章。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值