目录

题目描述

输入描述

输出描述

用例

题目分析

算法实现


题目描述

给定一个二维整数矩阵,要在这个矩阵中选出一个子矩阵,使得这个子矩阵内所有的数字和尽量大,我们把这个子矩阵称为和最大子矩阵,子矩阵的选取原则是原矩阵中一块相互连续的矩形区域。

输入描述

输入的第一行包含2个整数n, m(1 <= n, m <= 10),表示一个n行m列的矩阵,下面有n行,每行有m个整数,同一行中,每2个数字之间有1个空格,最后一个数字后面没有空格,所有的数字的在[-1000, 1000]之间。

输出描述

输出一行一个数字,表示选出的和最大子矩阵内所有的数字和。

用例

输入

3 4

-3 5 -1 5

2 4 -2 4

-1 3 -1 3

输出 20
说明 一个3*4的矩阵中,后面3列的子矩阵求和加起来等于20,和最大。

题目分析

这道题首先要考虑处理输入处理的问题,真的讨厌这种牛客式的编程模式,需要自己组装程序入参,还要处理多行输入,直接给个二维数组入参不行吗.....真的无语了,Leetcode就做的挺好的。

唉,抱怨归抱怨,下面是根据多行输入的信息,生成martrix二维数组的逻辑

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});let lines = [];
let n, m;
rl.on("line", (line) => {lines.push(line);// 输入第一行时,提取出m、nif (lines.length === 1) {[n, m] = lines[0].split(" ").map((ele) => parseInt(ele));}// 输入第一行后,再输入n行时,则开始启动算法程序if (lines.length - 1 === n) {// 干掉第一行输入,即lines中存储的全是就是matrix要素lines.shift();// matrix是算法程序的入参二维数组let matrix = [];// 将多行输入的matrix要素提取出来存到二维数组中lines.forEach((line) => {matrix.push(line.split(" ").map((ele) => parseInt(ele)).slice(0, m));});// 调用算法程序maxSubMatrixSum(matrix);// 将输入归0,重新接收下一轮lines.length = 0;}
});function maxSubMatrixSum(matrix) {console.log(JSON.stringify(matrix));
}

然后我们再来思考算法程序的编写。

看到这个题目标题,我很容易就联想到了最大子数组和,区别在于最大子数组和是一维的,而最大子矩阵和是二维的。

那么是不是有可能将最大子矩阵和的求解转成一维的呢?

下面是子矩阵可能存在的区域,即一行子矩阵,两行子矩阵,三行子矩阵

进一步简化,可得下图,即对求解下面每个区域的最大子矩阵

此时因为子矩阵的行数已经确定,因此我们可以将多行压缩为一行

此时对于最大子矩阵和的求解,就变为了最大子数组和的求解。

而最大子数组和的求解的状态转移方程我们已经在前一小结总结出来了:

dp[i] = max(dp[i-1], 0) + nums[i]。

还有一个难点就是二维数组压缩为一维数组的问题,解决思路如下,获取二维数组的行数rows、列数cols,创建一个长度为cols的一维数组,然后将二维数组双重for循环,外层遍历cols,内层遍历rows,这样每次循环就可以得到二维数组一个列上的所有元素,然后求和存入一维数组中,实现如下

function matrixZip(matrix) {let cols = matrix[0].length;let rows = matrix.length;let zip = new Array(cols).fill(0);for (let c = 0; c < cols; c++) {for (let r = 0; r < rows; r++) {zip[c] += matrix[r][c];}}return zip;
}

算法实现

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});let lines = [];
let n, m;
rl.on("line", (line) => {lines.push(line);// 输入第一行时,提取出m、nif (lines.length === 1) {[n, m] = lines[0].split(" ").map((ele) => parseInt(ele));}// 输入第一行后,再输入n行时,则开始启动算法程序if (lines.length - 1 === n) {// 干掉第一行输入,即lines中存储的全是就是matrix要素lines.shift();// matrix是算法程序的入参二维数组let matrix = [];// 将多行输入的matrix要素提取出来存到二维数组中lines.forEach((line) => {matrix.push(line.split(" ").map((ele) => parseInt(ele)).slice(0, m));});// 调用算法程序console.log(maxSubMatrixSum(matrix));// 将输入归0,重新接收下一轮lines.length = 0;}
});function maxSubMatrixSum(matrix) {let dp = [];for (let i = 0; i < matrix.length; i++) {dp.push(maxSubArraySum(matrix[i]));for (let j = i + 1; j < matrix.length; j++) {dp.push(maxSubArraySum(matrixZip(matrix.slice(i, j + 1))));}}return dp.sort((a, b) => b - a)[0];
}function maxSubArraySum(nums) {let dp = new Array(nums.length);let result = (dp[0] = nums[0]);for (let i = 1; i < nums.length; i++) {dp[i] = Math.max(dp[i - 1], 0) + nums[i];result = Math.max(result, dp[i]);}return result;
}function matrixZip(matrix) {let cols = matrix[0].length;let rows = matrix.length;let zip = new Array(cols).fill(0);for (let c = 0; c < cols; c++) {for (let r = 0; r < rows; r++) {zip[c] += matrix[r][c];}}return zip;
}

华为机试 - 最大矩阵和相关推荐

  1. 【强烈推荐收藏】坚持3个月爆肝华为机试108题C++全解(适合新手入门,就业必刷套题)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 金九银十,金三银四.当前正处于校招.社招的火热期,之前就想为正在筹备就业的同学们准备刷题宝 ...

  2. 【华为机试真题Java】从入门到入职-真题列表导读

    写在前面 本专栏有100+道题(持续更新中),都是往期的HW机试真题,根据过往同学的经验基本都会考到原题.大家有什么不懂的都可以留言. 华为机试有三道题目,第一道和第二道属于简单或中等题,分值为100 ...

  3. 牛客在线编程-华为机试-中等

    牛客在线编程题目-华为机试-中等 题号 题目 知识点 难度 通过率 HJ16 购物单 动态规划 中等 21.21% HJ17 坐标移动 字符串 中等 24.79% HJ20 密码验证合格程序 数组 字 ...

  4. 【华为机试】死记硬背没思路?一般人我劝你还是算了吧

    大家好,我是哪吒. 五月份之前,如果你参加华为OD机试,收到的应该是2022Q4或2023Q1,这两个都是A卷题. 5月10日之后,很多小伙伴收到的是B卷,那么恭喜你看到本文了,抓紧刷题吧.B卷新题库 ...

  5. 华为机试在线训练--牛客网(python)第四部分

    华为机试在线训练–牛客网(python) 第四部分(31~40) 第三十一题:[中级]单词倒排 题目描述 对字符串中的所有单词进行倒排. 说明: 1.每个单词是以26个大写或小写英文字母构成: 2.非 ...

  6. 集合篇10.华为机试(涮题记录2)

    华为机试 31.成绩排序(**not) 32. 矩阵乘法 33. 24点游戏算法(not) 34.配置文件恢复 35. 查找两个字符串a.b中的最长公共子串 36.MP3光标位置(not) 37.DN ...

  7. 华为机试108题(C 语言解答)

    Nowcoder题库链接:华为机试 HJ1 字符串最后一个单词的长度(字符串) 输入:hello nowcoder输出:8说明: 最后一个单词为nowcoder,长度为8 示例代码: HJ1.c #i ...

  8. 2022/7/26华为机试,Q2,上机迷迷糊糊的,搞完突然醒悟,自抱自泣!三道题附带答案

    21:52 2022/7/26华为机试三道题附带答案 备注:未ac,华为不难,难的是个人很难进入答题状态! 第一道 给定一个字符串,是工作记录的日志时间,时间为四段格式,AA:BB:CC:DDD 其中 ...

  9. 华为机试真题分类汇总

    1. 字符串 类别 题目 知识点 题目分值 / 难度 字符串 [华为机试真题 JAVA]TLV解析Ⅰ-100 字符串分隔.拼接.搜索 100/中等 字符串 [华为机试真题 JAVA]寻找相同子串-10 ...

最新文章

  1. [转载]Matlab之静态文本多行输出
  2. 艾伟_转载:探索.Net中的委托
  3. 使用Convirt 2.0.1管理虚拟机环境
  4. MySQL分组查询—简单使用
  5. oracle中execute函数,oracle Execute Immediate(sql语句)
  6. 线程之售票系统pthread_mutex,_lock,_unlock
  7. Java高级面试题解析(二):百度Java面试题前200页(精选)
  8. 崚 不能被 iconv(gb2312,utf-8 ,string)
  9. echarts最简单的南丁格尔玫瑰图+图例
  10. Linux系统 查看系统版本、CPU、内存、主频等信息
  11. c# 从MySQL往sharpmap中加载矢量数据图层(一)
  12. 大数据工程师和数据分析师有何区别
  13. 区块数据存储文件说明
  14. python爬虫之多线程、多进程爬虫
  15. win10+黑苹果 单硬盘 双系统 超简单安装 一看就会
  16. 微信小程序基于百度云实现图文识别(胎教级教程)
  17. cpu、内存、磁盘关系
  18. 使用moviepy.editor剪辑视频,批量截取视频片段
  19. python-django后台获取前端数据进行操作以及响应的方式
  20. Android RxBus

热门文章

  1. 网络io和磁盘io_在磁盘IO上,第1部分:IO的风味
  2. Spotfire经验总结—累积百分比(帕累托图)的绘制方法
  3. 天堂向左,深圳往右 第十三章第十四章
  4. 山东大学项目实训小组一——基于深度学习的AI视频剪辑器“易剪”
  5. [Go WebSocket] 为什么我选用Go重构Python版本的WebSocket服务?
  6. stm32 关于GPIO寄存器操作
  7. lzma和lz4的速度比较
  8. CSS3-弹性盒子模型
  9. SCIPY类库——最小二乘法应用
  10. linux下开启、关闭、重启mysql服务