LeetCode 861翻转矩阵后得分详细解法
1. 题目内容
有一个二维矩阵 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 <= 201 <= A[0].length <= 20A[i][j]是0或1
2. 分析
此题是被分类到贪心算法, 所以解决思路就是利用贪心算法, 因为矩阵可以把任意一行或者任意一列的数全部取反, 而要求取得最大的矩阵和。
求矩阵和的求法 是把每一行的二进制变成10进制, 这就有一个特性: 每一行的第一位为1 要 产生的效益比 它的下面的位之和为1产生的效益要大。 而我可以通过矩阵移动把第一行的第一位都变成1, 这样产生的效益是最大的。
当第一位都为1时,下面考虑每一列的数字, 对于除了第一列的其他列, 当这一列的1的个数小于0, 则可以通过列移动(取反)使得1的个数大于0, 这是产生的效益是最大的, 而且每一列的交换不会对前面的列或者后面的列产生影响当处理完最后一行 此时得到的矩阵就是 值最大的矩阵了
所以一共做的处理有两组
- 第一组处理第一列, 让第一列全变成1, 这样得到此时的最大
- 第二组 处理随后的列数让里面的1的个数 大于 0, 得到此时的最大
当处理完全部的列数 因为每一次处理完 都要比原来的值大,而且所有的处理都已完成, 此时的矩阵就是最大值的矩阵。
3.代码实现
class Solution {
public:
int matrixScore(vector<vector<int>>& A) {
int row = A.size();
int col = A[0].size();
int zeroCount = 0, sum = 0;
//处理第一列 把它变成
for (int i = 0; i < row; i++) {
if (A[i][0] == 0) {
for (int j = 0; j < col; j++) {
A[i][j] = A[i][j] ^ 1;
}
}
}
for (int j = 0; j < col; j++) {
//每一列的0个数
zeroCount = 0;
for (int i = 0; i < row; i++) {
if (A[i][j] == 0) {
zeroCount++;
}
}
//0个数多 就对此列交换
if (zeroCount > row/2) {
for (int i = 0; i < row; i++) {
A[i][j] = A[i][j] ^ 1;
}
}
}
//计算结果
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
sum += pow(2, col - j - 1) * A[i][j];
}
}
return sum;
}
};
代码可以更加简化 , 因为我只是需要得到一个值, 不需要得到矩阵, 可以直接通过规律来计算
代码来自 https://leetcode.com/problems/score-after-flipping-matrix/discuss/143722/C++JavaPython-Easy-and-Concise
int matrixScore(vector<vector<int>> A) {
//res 开始就是 把第一列的1 全部计算起来 (1 << (N - 1)) * M
int M = A.size(), N = A[0].size(), 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];
//计算其他列 max(cur, M - cur)表示1的个数
res += max(cur, M - cur) * (1 << (N - j - 1));
}
return res;
}
4. 总结
- 找到题目特性, 找到能贪心的点
5. 学习贪心算法
LeetCode 861翻转矩阵后得分详细解法的更多相关文章
- leetcode 861 翻转矩阵后的得分
1. 题目描述 2.思路分析: 1. 首先这里的翻转分为了行翻转和列翻转,我们这里只需要求如何翻转后得到最大值,有点贪心的思想,因为最大值一定是固定的 至于是什么路径到达的最大值不是我们所关心的,我们 ...
- LeetCode 中级 - 翻转矩阵后的得分(861)
有一个二维矩阵 A 其中每个元素的值为 0 或 1 . 移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0. 在做出任意次数的移动后,将该矩阵的每一 ...
- LeetCode翻转矩阵后的得分-Python3<六>
上一篇:LeetCode子域名访问计数-Python3.7<五> 题目:https://leetcode-cn.com/problems/score-after-flipping-matr ...
- [Swift]LeetCode861. 翻转矩阵后的得分 | 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 o ...
- [LeetCode] 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 o ...
- [LeetCode] Random Flip Matrix 随机翻转矩阵
You are given the number of rows n_rows and number of columns n_cols of a 2D binary matrix where all ...
- Java实现 LeetCode 519 随机翻转矩阵
519. 随机翻转矩阵 题中给出一个 n 行 n 列的二维矩阵 (n_rows,n_cols),且所有值被初始化为 0.要求编写一个 flip 函数,均匀随机的将矩阵中的 0 变为 1,并返回该值的位 ...
- C#版(击败100.00%的提交) - Leetcode 151. 翻转字符串里的单词 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- yzoi2226最小步数的详细解法
Description - 问题描述 在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”.有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字. ...
随机推荐
- 数据结构C语言实现----清空、销毁一个栈
代码如下: #include<stdio.h> #include<stdlib.h> typedef struct { char *base; char *top; int s ...
- 题解 洛谷 P6378 【[PA2010]Riddle】
首先不难看出对于本题的点与点之间的限制关系,我们可以考虑用\(2-SAT\)来解决,通过从状态\(x\)向状态\(y\)连一条有向边表示若状态\(x\)存在,那么状态\(y\)必须存在. 接下来的处理 ...
- Split Screen
Split Screen 是一个用来分屏的 bookmarklet 程序. 它通过 javascript 通信协议实现[1]. 特点 使用 HTML5 <dialog> 元素实现 使用 G ...
- 在Ubuntu 18.04中安装Wine QQ、微信、TIM
近日重新安装了Ubuntu 18.04,因此要重新安装一下Wine QQ.微信之类的,完整安装Wine系列软件一直是一个老大难的问题,网上搜集到的博客也比较零散,因此这里特此写篇博客记录一下 0. 这 ...
- 2. 妈呀,Jackson原来是这样写JSON的
没有人永远18岁,但永远有人18岁.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...
- MySQL之高级操作
新增数据: 基本语法: insert into 表名 [(字段列表)] values(列表值) 在数据插入的时候,假设主键对应的值已经存在,插入一定会失败 主键冲突: 当主键存在冲突的时候(Dupl ...
- C++的vector的使用方法
vector c++的vector的使用方法,创建,初始化,插入,删除等. #include "ex_vector.h" #include <iostream> #in ...
- C#中子类对基类方法的继承、重写和隐藏
提起子类.基类和方法继承这些概念,肯定大家都非常熟悉.毕竟,作为一门支持OOP的语言,掌握子类.基类是学习C#的基础.不过,这些概念虽然简单,但是也有一些初学者可能会遇到的坑,我们一起看看吧. 子 ...
- Redis的事件机制
目录 一.Redis的运行过程 二.事件数据结构 2.1 文件事件数据结构 2.2 事件事件数据结构 3.3 事件循环 三.事件的注册过程 3.1 文件事件的注册过程 3.2 时间事件的注册过程 四. ...
- luogu P2304 [NOI2015]小园丁与老司机 dp 上下界网络流
LINK:小园丁与老司机 苦心人 天不负 卧薪尝胆 三千越甲可吞吴 AC的刹那 真的是泪目啊 很久以前就写了 当时记得特别清楚 写到肚子疼.. 调到胳膊疼.. ex到根不不想看的程度. 当时wa了 一 ...