LeetCode - 861. 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. (可以选择一行或者一列,将所有0换成1,将所有1换成0)

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.(最后每行数字被看作二进制数,进算出所有行二进制数的和,作为score)

Returnthe 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

思路:

    最直观的想法就是,二进制越往左越决定整个数的大小,比如1000大于0111,所以需要先通过flip将所有行的第一位变成1(后边的都没有第一位重要),后边从第二列开始往后,让每一列中的1尽可能多(每一列的1重要程度一样)。由于除了0就是1,所以知道每一列中有多少1,就知道有多少0,max就知道这一列通过flip最多有多少个1(不需要真的进行flip操作),这样算到最后一列就知道最大sum是多少了。

int matrixScore(vector<vector<int>>& A)
{
    // m 行 n 列
    int m = A.size();
    int n = A[0].size();
    int sum = 0;
    for (int i = 0; i < m; i++)  
    {
        if(A[i][0] == 0)    
        {
            for (int t = 0; t < n; t++)
            {
                if(A[i][t] == 0)
                    A[i][t] = 1;
                else
                    A[i][t] = 0;
            }
        }
    }
    sum = (1 << (n - 1)) * m;
    for(int i = 1; i < n; i++)  // 从第二列开始
    {
        int cnt = 0;
        for (int j = 0; j < m; j++)
            cnt += A[j][i]; // 记录这一列有多少1
        sum += max(cnt, m - cnt) * (1 << n - 1 - i);            
    }
    return sum;
}

   想到后边的不需要真正进行flip操作,就想到其实一次flip操作都不需要,在每列计算时每次只需要判断,只需要判断这个数和跟他同一行的第一位数是不是一样,就知道假象的翻转后这个数是多少了,因为每一行要不flip,要不就flip一次,只要一样,这个数一定要从0变成1,或者保持是1不变(也就是这个数跟这一行第一位数一样,那假想的flip之后它一定是1),这样就省略了flip每一行让第一位数变为1的过程。

int matrixScore(vector<vector<int>> A) 
{
    int M = A.size(), N = A[0].size();
    int res = (1 << (N - 1)) * M;
    for (int j = 1; j < N; j++)     // 计算每一行的值,求和
    {
	int cur = 0;
        for (int i = 0; i < M; i++)
            cur += A[i][j] == A[i][0];
        res += max(cur, M - cur) * (1 << (N - j - 1));
    }
    return res;
}

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/81066818
今日推荐