点击上方蓝字设为星标

下面开始今天的学习~

力扣  861. 翻转矩阵后的得分(点击文末阅读原文查看题目)题目描述有一个二维矩阵 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. 1 <= A.length <= 20

  2. 1 <= A[0].length <= 20

  3. A[i][j] 是 0 或 1

方法:贪心

根据题意,能够知道一个重要的事实:给定一个翻转方案,则它们之间任意交换顺序后,得到的结果保持不变。因此,我们总可以先考虑所有的行翻转,再考虑所有的列翻转。不难发现一点:为了得到最高的分数,矩阵的每一行的最左边的数都必须为 1。为了做到这一点,我们可以翻转那些最左边的数不为 1 的那些行,而其他的行则保持不动。当将每一行的最左边的数都变为 1 之后,就只能进行列翻转了。为了使得总得分最大,我们要让每个列中 1 的数目尽可能多。因此,我们扫描除了最左边的列以外的每一列,如果该列 0 的数目多于 1 的数目,就翻转该列,其他的列则保持不变。实际编写代码时,我们无需修改原矩阵,而是可以计算每一列对总分数的「贡献」,从而直接计算出最高的分数。假设矩阵共有 m 行 n 列,计算方法如下:

  • 对于最左边的列而言,由于最优情况下,它们的取值都为 1,因此每个元素对分数的贡献都为 2^(n - 1) ,总贡献为 m * 2^(n - 1)。

  • 对于第 j 列(j > 0,此处规定最左边的列是第 0 列)而言,我们统计这一列 0,1 的数量,令其中的最大值为 k,则 k 是列翻转后的 1 的数量,该列的总贡献为 k*2^(n - j - 1)。需要注意的是,在统计 0,1 的数量的时候,要考虑最初进行的行反转

C++ 

class Solution {public:    int matrixScore(vector<vector<int>>& A) {        int m = A.size(), n = A[0].size();        int ret = m * (1 << (n - 1));        for (int j = 1; j < n; j++) {            int nOnes = 0;            for (int i = 0; i < m; i++) {                if (A[i][0] == 1) {                    nOnes += A[i][j];                } else {                    nOnes += (1 - A[i][j]); // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j]                }            }            int k = max(nOnes, m - nOnes);            ret += k * (1 << (n - j - 1));        }        return ret;    }};

Java

class Solution {    public int matrixScore(int[][] A) {        int m = A.length, n = A[0].length;        int ret = m * (1 << (n - 1));        for (int j = 1; j < n; j++) {            int nOnes = 0;            for (int i = 0; i < m; i++) {                if (A[i][0] == 1) {                    nOnes += A[i][j];                } else {                    nOnes += (1 - A[i][j]); // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j]                }            }            int k = Math.max(nOnes, m - nOnes);            ret += k * (1 << (n - j - 1));        }        return ret;    }}

Golang

func matrixScore(a [][]int) int {    m, n := len(a), len(a[0])    ans := 1 << (n - 1) * m    for j := 1; j < n; j++ {        ones := 0        for _, row := range a {            if row[j] == row[0] {                ones++            }        }        if ones < m-ones {            ones = m - ones        }        ans += 1 << (n - 1 - j) * ones    }    return ans}

JavaScript

var matrixScore = function(A) {    const m = A.length, n = A[0].length;    let ret = m * (1 << (n - 1));    for (let j = 1; j < n; j++) {        let nOnes = 0;        for (let i = 0; i < m; i++) {            if (A[i][0] === 1) {                nOnes += A[i][j];            } else {                nOnes += (1 - A[i][j]); // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j]            }        }        const k = Math.max(nOnes, m - nOnes);        ret += k * (1 << (n - j - 1));    }    return ret;};

C

int matrixScore(int** A, int ASize, int* AColSize) {    int m = ASize, n = AColSize[0];    int ret = m * (1 << (n - 1));    for (int j = 1; j < n; j++) {        int nOnes = 0;        for (int i = 0; i < m; i++) {            if (A[i][0] == 1) {                nOnes += A[i][j];            } else {                nOnes += (1 - A[i][j]);  // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j]            }        }        int k = fmax(nOnes, m - nOnes);        ret += k * (1 << (n - j - 1));    }    return ret;}

复杂度分析

  • 时间复杂度:O(mn),其中 m 为矩阵行数,n 为矩阵列数。

  • 空间负责度:O(1)。

BY / 

本文作者:力扣

编辑&版式:霍霍

声明:本文归“力扣”版权所有,如需转载请联系。

点个在看,少个 bug?

将矩阵转为一行_LeetCode 力扣官方题解 | 861. 翻转矩阵后的得分相关推荐

  1. int类型年月怎么区间查询_LeetCode 力扣官方题解 | 57.插入区间

    点击上方蓝字设为星标 下面开始今天的学习-力扣  57. 插入区间(点击文末阅读原文查看题目)题目描述给出一个无重叠的 ,按照区间起始端点排序的区间列表.在列表中插入一个新的区间,你需要确保列表中的区 ...

  2. leetcode c++未初始化_LeetCode 力扣官方题解 | 538. 把二叉搜索树转换为累加树

    力扣 538. 把二叉搜索树转换为累加树(点击查看题目) 力扣​leetcode-cn.com 题目描述 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater ...

  3. java邮箱验证正则表达式_LeetCode 力扣官方题解 | 468.验证 IP 地址

    点击上方蓝字设为星标 下面开始今天的学习-力扣 468. 验证 IP 地址(点击文末阅读原文查看题目)题目描述 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址. IPv4 地 ...

  4. LeetCode 力扣算法题解汇总,All in One

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: https://fuxuemingzhu.cn 关键词:LeetCode,力扣,算法,题解,汇总,解析 把自己刷过的所有题目做一个整理, ...

  5. 将矩阵转为一行_矩阵与矩阵乘积简介

    作者|Hadrien Jean 编译|VK 来源|Towards Data Science 原文链接:https://towardsdatascience.com/introduction-to-ma ...

  6. 将矩阵转为一行_理解矩阵乘法

    理解矩阵乘法 考研需要考一门课<线性代数>,这门课其实是教矩阵. 刚学的时候,还蛮简单的,矩阵加法就是相同位置的数字加一下. 矩阵乘法也类似,矩阵乘以一个常数,就是所有位置都乘以这个数. ...

  7. 将矩阵转为一行_初等变换不会改变矩阵的秩

    换法变换 情况一:如下图所示,若矩阵A的秩为r,任取一个矩阵A的r+1阶零子式(阴影部分),将A的第一行与第六行交换变为B矩阵,对于因为交换A的第一行与第六行交换变成B没有碰到r+1阶零子式,所以互换 ...

  8. LeetCode 力扣 算法题解 1109. 航班预订统计(Corporate Flight Bookings) n 个航班,它们分别从 1 到 n 进行编号,请返回每个航班预定的座位总数。

    文章目录 一.题目描述 示例 1: 示例 2: 提示: 二.Python解题 1.Python代码展示 2.程序逻辑解释 3.复杂度分析 官方解释 三.测试反思 1.历史提交记录 2.提交失败记录 3 ...

  9. LeetCode 力扣C++题解 575. 分糖果

    题目描述:给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果.你需要把这些糖果平均分给一个弟弟和一个妹妹.返回妹妹可以获得的最大糖果的种类数.(难度:简单) 原题链接: ...

最新文章

  1. 【树型DP】BZOJ1564 二叉查找树(noi2009)
  2. Protocol Buffer Java应用实例
  3. Fetcher类的工作流程
  4. web browser 发展史
  5. 漫画:程序员相亲?哈哈哈哈哈哈
  6. python异常值检测_python – 使用RPCA的异常值
  7. [css] 如何让一个块元素绝对居中?
  8. 有序二叉树c语言,二叉搜索树(BST)的实现(C语言)(原创)
  9. 如何在Mac电脑上的聚焦搜索中隐藏内容?
  10. OSChina 周四乱弹 —— 电脑上都有监视器
  11. [iOS] UIScrollView (UIWebView) 截长屏功能实现
  12. c语言this什么意思,JavaScript 中的this是什么?它到底做了什么?
  13. 人生何尝不是一盘“大富翁”呢
  14. 无线网络WPA-PSK加密破解
  15. Eclipse快捷键设置和Eclipse中的常用快捷键
  16. ‘pom.xml‘ has syntax errors
  17. Selenium(2): DOM元素定位、操作
  18. 名帖232 张雨 行书《行书帖选》
  19. html 手机录视频,手机自带的录屏功能真是太强大了,完全秒杀第三方工具
  20. nas 微型计算机,NETGEAR无线路由器和NAS试用

热门文章

  1. 动态换ip如何实现_动态IP可以实现哪些功能及用途
  2. prometheus变量_TiKV 源码解析系列文章(四)Prometheus(下)
  3. 机器学习第三篇:详解朴素贝叶斯算法
  4. 一步步把 SAP UI5 应用部署到 SAP BTP Kyma 运行环境中去
  5. ABAP Development Tool 代码模板和其他一些实用技巧汇总
  6. 关于SAP Commerce Cloud CORS policy的设置问题
  7. SAP Spartacus cost center list里通向detail页面的url生成逻辑
  8. SAP Spartacus cost center list class的赋值逻辑
  9. SAP Spartacus里,点击checkbox右边的span文本,不会触发checkbox勾选的原因
  10. SAP Spartacus把指定产品添加到购物车的API