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

题目描述:
给定由若干 0 和 1 组成的矩阵 matrix,从中选出任意数量的列并翻转其上的 每个 单元格。翻转后,单元格的值从 0 变成 1,或者从 1 变为 0 。
回经过一些翻转后,行与行之间所有值都相等的最大行数。

示例 1:
输入:[[0,1],[1,1]]
输出:1
解释:不进行翻转,有 1 行所有值都相等。

示例 2:
输入:[[0,1],[1,0]]
输出:2
解释:翻转第一列的值之后,这两行都由相等的值组成。

示例 3:
输入:[[0,0,0],[0,0,1],[1,1,0]]
输出:2
解释:翻转前两列的值之后,后两行由相等的值组成。

提示:
1 <= matrix.length <= 300
1 <= matrix[i].length <= 300
所有 matrix[i].length 都相等
matrix[i][j] 为 0 或 1

方法1:
主要思路:解题链接汇总
(1)找出各个行相同的和完全不相同的行作为一组,分组中数量最多的行数即为结果;
(2)完全不相同的行,刚好可以通过改变一半的值获得相同的数字分布;

class Solution {
public:
    bool not_same(vector<vector<int>>&matrix,int i,int j){//判断两行是否完全不相同
        for(int k=0;k<matrix[0].size();++k){
            if(matrix[i][k]==matrix[j][k]){
                return false;
            }
        }
        return true;
    }
    bool same(vector<vector<int>>&matrix,int i,int j){//判断两行是否完全相同
        return matrix[i]==matrix[j];
    }
    int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
        vector<bool> visited(matrix.size(),false);//标识访问过的行
        int res=0;
        int cur=0;
        for(int i=0;i<matrix.size();++i){
            if(visited[i]){//跳过访问过的行
                continue;
            }
            visited[i]=true;//标识访问过的行
            ++cur;//新的一组
            for(int j=0;j<matrix.size();++j){
                if(visited[j]){
                    continue;
                }
                if(not_same(matrix,i,j)||same(matrix,i,j)){
                    visited[j]=true;
                    ++cur;
                }
            }
            //根据当前组的数量,更行可能的更大的组数
            res=max(res,cur);
            cur=0;
        }
        return res;
    }
};

方法2:
主要思路:
(1)哈希;
(2)主要判读思想和方法一一致,就是将完全相同的和完全不相同的行统一为一组;
(3)只不过,这里将行转为对应的字符串,并根据每行的首个数字的状态,决定转换的方式;

class Solution {
public:
    int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
        unordered_map<string,int> mp;
        for(vector<int>&cur_row:matrix){
            string cur_str;
            if(cur_row[0]==1){
                for(int& i:cur_row){
                    if(i==1){
                        cur_str+='1';
                    }
                    else{
                        cur_str+='0';
                    }
                }
            }
            else{
                for(int& i:cur_row){
                    if(i==1){
                        cur_str+='0';
                    }
                    else{
                        cur_str+='1';
                    }
                }
            }
            ++mp[cur_str];
        }
        int res=0;
        for(auto&it:mp){
            res=max(res,it.second);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值