LeetCode/按列翻转得到最大值等行数

你可以从中选出任意数量的列并翻转其上的每个单元格。(即翻转后,单元格的值从 0 变成 1,或者从 1 变为 0 )
返回经过一些翻转后,行与行之间所有值都相等的最大行数

1. 编码 + 哈希

首先,可以确定的是通过元操作列翻转,最后必然可以使得至少一行的数值相等
这里我们把第一列固定(由于对称性和任意翻转),第一列翻转与否不影响
接着考察后面的每一列与第一列的相等关系,这里可以使用异或操作,值为0表示相等,值为1表示相反
相等与相反的行,最终必然不会出现在同一个结果中,这里便产生了差异
我们可以对每一列相等的行编码为1,相异编码为0,遍历完所有列之后获得一条字符串,字符串相同即代表两者可以出现在同一结果中
只需取出相同次数最多的编码即可,这里可以使用哈希计数

class Solution {
public:
    int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        unordered_map<string, int> mp;
        for (int i = 0; i < m; i++) {//遍历行
            string s = string(n, '0');
            for (int j = 0; j < n; j++) //遍历列,对每行进行编码
                s[j] = '0' + (matrix[i][j] ^ matrix[i][0]); //每次只跟首位对比,如果该位与首位不同,计为1
            mp[s]++;
        }
        //因为每次的元操作是对整个列进行变换,如果两行编码不同,则无法通过任何操作同时满足条件,所以只能选取具有最多相同编码的行,使其满足条件
        int res = 0;
        for (auto &[k, v] : mp) 
            res = max(res, v);
        return res;
    }
};
posted @ 2023-05-15 02:47  失控D大白兔  阅读(28)  评论(0)    收藏  举报