程序员面试金典——18.12最大和子矩阵
程序员面试金典——18.12最大和子矩阵
Solution1:
参考网址:
[1]https://www.cnblogs.com/GodA/p/5237061.html 思想讲的很清楚~
[2]https://www.nowcoder.com/profile/963612/codeBookDetail?submissionId=15224519
思路:
动态规划
我们来分析一下最优子结构,若想找到n个数的最大子段和,那么要找到n-1个数的最大子段和,这就出来了。我们用b[i]来表示a[0]…a[i]的最大子段和,b[i]无非有两种情况:
(1)最大子段一直连续到a[i]
(2)以a[i]为首的新的子段 。
由此我们可以得到b[i]的状态转移方程:b[i]=max{b[i−1]+a[i],a[i]}b[i]=max{b[i−1]+a[i],a[i]}b[i]=max\{b[i-1]+a[i],a[i]\}。最终我们得到的最大子段和为max{b[i],0<=i<n}max{b[i],0<=i<n}max\{b[i], 0,
这跟最大子矩阵有什么关系呢?当然有关系学啦!二维就是一维的扩展,把二维压扁不就变成一维了吗?
我们假设所求N*N的矩阵的最大子矩阵是从i列到j列,q行到p行,如下图所示(假设下标从1开始)
a[1][1] a[1][2] ······ a[1][i] ······ a[1][j] ······ a[1][n]
a[2][1] a[2][2] ······ a[2][i] ······ a[2][j] ······ a[2][n]
······
a[q][1] a[q][2] ······ a[q][i] ······ a[q][j] ······ a[q][n]
······
a[p][1] a[p][2] ······ a[p][i] ······ a[p][j] ······ a[p][n]
······
a[n][1] a[n][2] ······ a[n][i] ······ a[n][j] ······ a[n][n]
最大子矩阵就是对角线为a[q][i]-a[p][j]的子矩阵,如果把最大子矩阵同列的加起来,我们可以得到一个一维数组{a[q][i]+⋅⋅⋅⋅⋅⋅+a[p][i],⋅⋅⋅⋅⋅⋅,a[q][j]+⋅⋅⋅⋅⋅⋅+a[p][j]}{a[q][i]+······+a[p][i],······,a[q][j]+······+a[p][j]}\{a[q][i]+······+a[p][i], ······ , a[q][j]+······+a[p][j]\} ,现在我们可以看出,这其实就是一个一维数组的最大子段问题。如果把二维数组看成是纵向的一维数组和横向的一维数组,那问题不就迎刃而解了吗?把二维转换成了我们刚刚解决了的问题。
class SubMatrix {
public:int sumOfSubMatrix(vector<vector<int> > mat, int n) {// write code hereif(n <= 0) return 0;int maxVal = INT_MIN;for(int i = 0; i < n; i++) {vector<int> temp(mat[i]); //temp是一维行向量maxVal = max(maxVal, helper(temp));//先得到第i行的最大和for(int j = i + 1; j < n; j++) { //依次循环下面的n-i行,把每行里的n个数加到第i行中for(int k = 0; k < n; k++) { //i+1 =< j <= n-1,把第j行中n个数加到第i行中temp[k] += mat[j][k];}maxVal = max(maxVal, helper(temp));//每当加完1行后就判断1次最大和}}return maxVal;}//求连续数组最大和,动态规划思想int helper(vector<int>& vec) { //求一维数组最大和int f = vec[0];int result = f;for(int i = 1; i < vec.size(); i++) {f = max(f+vec[i], vec[i]);result = max(result, f);}return result;}
};
PS:一道很不错的动态规划题,理解他着实费了点功夫
程序员面试金典——18.12最大和子矩阵相关推荐
- 程序员面试金典——18.13 最大字母矩阵
程序员面试金典--18.13 最大字母矩阵 在牛客网上把此题的难度给大大降低了......... Solution1: 参考网址:https://www.nowcoder.com/questionTe ...
- 【To Do】程序员面试金典——18.11最大子方阵
程序员面试金典--18.11最大子方阵 Solution1:我的答案.最笨的方法,时间复杂度是O(n3)O(n3)O(n^3) class SubMatrix { public:int maxSubM ...
- 程序员面试金典——18.10字符串变换
程序员面试金典--18.10字符串变换 Solution1: 我的答案.穷举法,个人认为此题还是有点难度的... 利用了倒推法以及很高的时间复杂度才解决,并不值得推崇呀. class Change { ...
- 程序员面试金典——18.9实时中位数
程序员面试金典--18.9实时中位数 Solution1:我的答案.利用排序,比较弱智.. class Middle { public:vector<int> getMiddle(vect ...
- 程序员面试金典——18.7最长合成字符串
程序员面试金典--18.7最长合成字符串 参考网址:https://www.nowcoder.com/profile/2896594/codeBookDetail?submissionId=13543 ...
- 【To Do!】程序员面试金典——18.8子串判断
程序员面试金典--18.8子串判断 Solution1:我的答案 利用了C++ STL中自带的find函数,有点投机取巧的意思,正统方法是用trie树(单词查找树)来做,那就麻烦了许多 class S ...
- 程序员面试金典——18.4 2的个数
程序员面试金典--18.4 2的个数 Solution1:经典通法,得牢记啊... 此题在<剑指offer>中出现过,里面分析的比较到位 https://blog.csdn.net/all ...
- 程序员面试金典——18.5单词最近的距离
程序员面试金典--18.5单词最近的距离 Solution1:我的答案,时间复杂度为O(n2)O(n2)O(n^2). class Distance { public:int getDistance( ...
- 程序员面试金典——18.1另类加法
程序员面试金典--18.1另类加法 Solution1:还是参考剑指上的思路.. class UnusualAdd {public:int addAB(int A, int B) {// write ...
最新文章
- superset的安装和使用--docker
- 拷贝eclipse 工作空间 workspace 步骤
- FTP服务器之vsftp
- php和python哪个用了开发web好-php与python谁更适合web开发?为什么?
- 读《系统虚拟化-原理与实现》-第二章
- 习题:编写一个程序,请输入两个数字,并判断两个数字的大小。
- 埃尔米特(Hermite)插值及其MATLAB程序
- 数据结构排序算法总结
- 此声明没有存储类或类型说明符
- git 本地 更新到 仓库 仅仅 操作系统课程设计
- Win7服务器搭建实例教程:教你Win7如何搭建Web服务器【转载】
- NP、OSPF虚链路
- 基于Android的健康打卡系统,基于Android平台的个人健康管理系统
- 性能测试--33Jvisualvm远程监控Linux服务器方案
- dede织梦CMS采集过滤规则
- Beyond Compare 激活解决办法
- Web media radar|web媒体雷达
- Axure知识点:如何制作输入关键词模糊搜索功能?
- 斐讯R1音箱安装悟空遥控,并实现DLNA推送
- 计算机操作系统 - 目录
热门文章
- VML编程之------oval圆rect矩型《VML极道教程》原著:沐缘华
- PyTorch 入坑四 梯度、链式法则、计算图与反向传播
- java 数组 null值_数组的元素String在java中包含null
- import python settings from_python settings 中通过字符串导入模块
- oracle字段怎么写,oracle修改字段名的语句怎么写_数据库,oracle,字段名
- vue的路由怎么换端口_vue.js如何更改默认端口号8080为指定端口的方法
- html 转换成 pdf js,JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
- ubuntu vscode_17. ubuntu设为服务器+vscode远程开发
- mysql tb级数据库_4.5万字手把手教你实现MySQL TB级数据存储!!
- Python核心编程朱红庆_Python编程语言的核心是什么?